4

考虑 GHCi 会话中的这个示例:

Prelude> :set -XRankNTypes
Prelude> let bar :: (forall a.[a]->[a]) -> [Int]; bar f = f [1,2,3]

这定义了一个barrank-2 类型的函数。因此,类型推断不应该能够推断出正确的类型:

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 中得到了特殊处理,或者指出我错在哪里。

4

1 回答 1

4

在存在更高级别类型的情况下,类型推断的主要问题是推断 lambda 绑定变量的多态类型。在您的第一个示例中,唯一正确的键入方法foo是将多态类型分配给f. 在您的第二个示例中,不需要这样的东西。相反,baz它只是bar. 在没有额外类型注释的情况下,仅仅应用一个更高级别的多态函数,没有任何 lambda 抽象应该总是可行的。

另请参阅GHC 用户指南中的相应部分以及各种研究论文。

于 2013-07-24T19:24:58.730 回答