我们可以使用参数定义类型同义词,这在与实际类型一起使用时可以很好地工作:
type MyType t = t String String
data Test a b = Test a b
f :: MyType Test
f = undefined
main = undefined
编译此命令不会导致任何错误:
$ghc --make test.hs
[1 of 1] Compiling Main ( test.hs, test.o )
Linking test ...
但是,当Test
是类型同义词时,这是行不通的:
type MyType t = t String String
data Test a b = Test a b
type Test' a b = Test a b
f :: MyType Test'
f = undefined
main = undefined
出现以下错误:
$ghc --make test.hs
[1 of 1] Compiling Main ( test.hs, test.o )
test.hs:7:6:
Type synonym Test' should have 2 arguments, but has been given none
In the type signature for `f': f :: MyType (Test')
令我百思不解的是,Test'
正在被应用到两个参数,所以为什么GHC抱怨我没有传递参数?
类型同义词不应该完全透明并且无法与其他类型区别吗?
有什么方法可以实现预期的行为?
根据Haskell报告类型,同义词不能部分应用:
类型
T
同义词声明引入的类型构造函数符号不能部分应用;如果T
没有全部参数,则使用它是一个静态错误。
特别是,在展开类型同义词之前会进行检查,这意味着在表达式中:
MyType Test'
该检查在扩展之前执行MyType
,因此Test'
部分应用结果。
然而,这是可能实现使用GHC这种行为LiberalTypeSynonyms
的延伸。此扩展将类型同义词视为宏,将对其进行扩展而无需进行任何检查,然后类型检查器将查看是否部分应用了类型同义词。
在类型同义词扩展之前,仍然要进行种类推断。
请注意,即使在这种情况下,类型同义词也不能部分应用,例如:
Test' Int
仍然是一个错误。但是,您现在可以使用类型同义词来完全应用其他类型同义词,而不会出现错误。
允许部分应用类型同义词将使类型推断变得不确定,因此无法轻松地在该方向上扩展类型系统。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句