forall a之间有什么区别? [a]和[forall a。一个]?

时间:2010-10-18 17:48:55

标签: haskell polymorphism

标题和标签应该充分解释这个问题。

3 个答案:

答案 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