AFAIK,只有类型存在于Haskell中的值,而不是类型构造函数。 Either
是类* -> * -> *
的二进制类型构造函数。 Left
和Right
都将此类型构造函数应用于单个类型,该类型由传递的值提供。这是否意味着在两种情况下Either
仅部分应用,因此仍然是一个等待缺失类型参数的类型构造函数?
let x = Right 'x' -- Either a Char
x
的类型为Either a Char
。我认为这种类型会有* -> *
种。这显然是多态类型,而不是基础类型。然而Either a Char
可以居住'x'
等值。
我怀疑类型变量a
是Right
案例的幻像类型。 b
Left
。我知道与Const
相关的幻像类型,其中根本没有使用相应的类型变量。我是正确的大头钉吗?
答案 0 :(得分:8)
AFAIK,只有类型存在于Haskell中的值,而不是类型构造函数。
专注于。
Left
和Right
都将此类型构造函数应用于单个类型
你不能这么说。 Left
和Right
根本不存在于类型语言中,因此它们不会对任何类型应用任何内容,它们仅适用于值。
x
的类型为Either a Char
。我认为这种类型会有* -> *
您需要区分函数/构造函数参数和类型变量。它基本上是free and bound variables之间的区别。 Either a Char
仍然有*
,而不是* -> *
,因为它已经应用于a
。是的,这是一个类型变量,但它仍然是一个已经应用的参数。
然而
Either a Char
可以居住'x'
等值。
不完全 - 它可以居住在像Right 'x'
这样的值。
我怀疑类型变量
的a
是Right
案例的幻像类型。b
Left
有点,但我不会称之为“幽灵”,因为你不能只计算Left
或Right
。除非您选择Either Void b
,否则至少不会,但在这种情况下,您没有a
变量。
答案 1 :(得分:1)
我认为,当且仅当类型变量的选择不限制可以将哪些值传递给类型的构造函数时,类型变量才是幻像。重要的是这是一个以类型为中心的定义。它仅通过查看类型定义来确定,而不是根据类型的某个特定值来确定。
值String
中是否显示Left 5 :: Either Int String
类型的值没有问题?一点也不。重要的是,String
中Either Int String
的选择会阻止Right ()
进行类型检查。
答案 2 :(得分:1)
Haskell具有“隐式通用量化”,这意味着类型变量具有隐式forall
。 Either a Int
相当于forall a. Either a Int
。
考虑forall
的一种方法是它就像一个lambda,但是对于类型变量。如果我们对类型应用程序使用语法@
,那么,您可以“应用”一个类型并获取一个新类型。
let foo = Right 1 :: forall a. Either a Int
foo @Char :: Either Char Int
foo @Double :: Either Double Int