从GHCi会话中考虑这个例子:
Prelude> :set -XRankNTypes
Prelude> let bar :: (forall a.[a]->[a]) -> [Int]; bar f = f [1,2,3]
这定义了具有rank-2类型的函数bar
。因此,类型推断不应该能够推断出正确的类型:
Prelude> let foo f = bar f
事实上,
<interactive>:7:17:
Couldn't match type `t' with `[a] -> [a]'
`t' is a rigid type variable bound by
the inferred type of foo :: t -> [Int] at <interactive>:7:5
In the first argument of `bar', namely `f'
In the expression: bar f
In an equation for `foo': foo f = bar f
令人惊讶的是,如果我们以无点自由风格编写相同的文章,那就可以了:
Prelude> let baz = bar
Prelude> :t baz
baz :: (forall a. [a] -> [a]) -> [Int]
类型推断如何在这里推断出更高级别的类型? 任何人都可以确认这是在GHC中特别处理的,或指出我错误的地方。
答案 0 :(得分:4)
存在更高级别类型时类型推断的主要问题是推断λ绑定变量的多态类型。在第一个示例中,键入foo
的唯一正确方法是将多态类型指定给f
。在你的第二个例子中,不需要这样的东西。相反,baz
只是bar
的一个(普通)部分应用。在没有任何类型注释的情况下,应该始终可以应用更高级别的多态函数,而无需任何lambda抽象。
另请参阅GHC User's Guide中的相应部分以及各种研究论文。