功能箭头右侧的forall是什么意思?

时间:2013-10-10 10:04:28

标签: haskell ghc

Section 7.12.5 of the GHC Users Guide的主题是更高级别的多态性。有一些示例有效类型,其中包括:

f4 :: Int -> (forall a.a->a)

现在我想知道这种类型意味着什么。我认为它与:

相同
f4' :: forall a. Int -> a -> a

如果是这样的话,我们是否可以通过心理上的方式将 forall 像上面的那样(显示在最右边的箭头右侧)向左移动,假设在其余部分中没有出现具有相同名称的类型变量类型(但这可以简单地重命名处理)?

例如,以下内容仍然是正确的,不是吗:

f5 :: Int -> (forall a. (forall b. b -> a) -> a)
f5' :: forall a. Int -> (forall b. b -> a) -> a

感谢有见地的回答。

背景:在这个talk about lenses by SPJ中,我们有:

type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s

然后,当你构成它们时,你的结果就是这样的镜头类型。 因此,我只是想知道我的直觉是否正确,结果中的结果并不重要 - 因为同义词的类型,它只是“偶然”出现。否则,我想要了解的f4,f4'和f5,f5'类型之间必定存在一些差异。

这是一个ghci会议:

Prelude> let f5 :: Int -> (forall a. (forall b. b -> a) -> a); f5 i f = f i
Prelude> :t f5
f5 :: Int -> (forall b. b -> a) -> a
Prelude> 

看起来GHC同意我的意见,至少在这种情况下......

1 个答案:

答案 0 :(得分:4)

您的示例中的

f4可以进行普遍量化,因为Int -> (forall a. a -> a)forall a. Int -> (a -> a)基本相同。

但是我们不能在这个Rank2类型(forall a. a -> a) -> (forall b. b -> b)中对你进行类比。此类型与forall b. (forall a. a -> a) -> (b -> b)基本相同。但是移出第一个forall(forall a b. (a -> a) -> (b -> b))实质上会改变该类型的语义。

f :: (forall a. a -> a) -> (forall b. b -> b) -- Rank 2
g :: forall a b. (a -> a) -> (b -> b)         -- Rank 1

要查看差异,您可以将a中的g实例化为Int,从而可以将类型为Int -> Int的函数传递给g。另一方面,f的参数必须被普遍量化(在函数类型之前由forall指定)并且应该适用于所有类型(这样的函数的示例是id)。

Here是对更高等级类型的一个很好的解释。