标题和标签应该充分解释这个问题。
答案 0 :(得分:19)
答案 1 :(得分:6)
类型forall a. [a]
表示对于任何单一类型,它都是包含该类型的列表。这也是普通[a]
的含义,也是[]
的类型,空列表数据构造函数。
类型[forall a. a]
意味着您有一个具有多态类型的值列表,也就是说,每个值都是任何可能类型的值,不一定与列表中的其他元素相同。没有可能的值可以具有类型forall a. a
,因此这也必须是空列表。
然后,区别在于,第一个可以用作任何类型的列表(根据定义,基本上),后者不能用作任何具体类型的列表,因为没有办法把它固定到任何一种类型。
要解决标记 - 存在类型是在某个范围内将实例化为某种未知的具体类型的类型。它可以是任何东西,所以用上面的forall a. a
来表示。为了确保具有存在类型的任何内容仅在实际类型可用的范围内使用,编译器会阻止存在类型“转义”。
将forall
量词视为lambda表达式可能有所帮助 - 它引入了一个新的类型变量并在某个范围内绑定了该标识符。在该范围之外,标识符没有意义,这就是forall a. a
非常无用的原因。
答案 2 :(得分:4)
用于类型forall
表示交集。所以forall a. a
是所有类型或类似Int ∩ String ∩ ...
的交集,它似乎给出了空集,但每个类型在Haskell中都有一个名为bottom或⊥或undefined
的额外元素。从此我们得到forall a. a = {⊥}
。实际上我们可以定义一个只包含底部的类型:
data Zero
完成此设置后,请查看以[forall a. a]
开头的类型。它定义的是底部列表或[Zero]
,其中包含元素[], [undefined], [undefined, undefined], ...
。让我们在ghci中查看:
> let l = [undefined, undefined]::[Zero]
> :t l
l :: [Zero]
以类似的方式forall a. [a]
是所有列表类型的交集,自∩[a] = [∩a]
起,这又是[Zero]
。
要做最后的检查,请定义:
type L = forall a. [a]
type U = [forall a. a]
和ghci:
> let l2 = [undefined, undefined]::L
> let l3 = [undefined, undefined]::U
> :t l2
l2 :: [a]
> :t l3
l3 :: U
请注意l2::[a]
,解释是Haskell在所有多态类型之前放置了一个隐式forall
。