在haskell中使用范围类型变量和y组合子时出现奇怪的错误

时间:2011-05-04 14:59:38

标签: haskell type-systems y-combinator higher-rank-types

所以我正在使用y-combinator和匿名函数,我遇到了这个奇怪的错误:

Couldn't match expected type `t0 -> t1 -> t2'
            with actual type `forall b. b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `Int -> forall b. b -> [b] -> [b]' has only one

source code that creates the errorversion that I eventually got working

如果我modify the types slightly to avoid Rank N polymorphism (use forall b. Int -> b -> [b] -> [b]),则错误类似:

Couldn't match expected type `t0 -> t1 -> t2 -> t3'
            with actual type `forall b. Int -> b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `forall b. Int -> b -> [b] -> [b]' has none

有人可以向我解释为什么forall b. b -> [b] -> [b]没有参数吗?

3 个答案:

答案 0 :(得分:2)

由于您使用的是GHC 7,因此它似乎与http://hackage.haskell.org/trac/ghc/ticket/4347中报告的错误具有相同的根本原因。虽然该错误报告讨论了不可预测的多态性,但它似乎最有可能出现在更高级别多态中的统一问题。在您的情况下,它由forall的展示位置触发,这使得类型在语法上排名为-2。

请注意,这不是一个真正的错误。所提供的进一步说明清楚地表明这是预期的行为,因为不推断出类型的多态实例化,包括秩-N类型和不可预测类型。小心添加类型签名可以使其工作。

但是,由于这种类型的目的不是更高级别,在你的情况下,最好摆脱它。

答案 1 :(得分:0)

你想要

吗?
forall b. Int -> b -> [b] -> [b]

或者真的

Int -> forall b . b -> [b] -> [b]

我会读到后者:一个接受Int并返回 SOMETHING OPAQUE的函数,它最可能不是你认为的

答案 2 :(得分:0)

我的猜测是你写错了类型。

删除类型注释会有所帮助,从而减少混淆错误:

A.hs:7:76:
    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the third argument of `replaceNth', namely `arg'
    In the expression: replaceNth m (replaceNth n v (arg !! m)) arg

所以

 \m n v arg -> replaceNth m (replaceNth n v (arg !! m)) arg

已经有问题了。


排名N类型和词汇范围类型变量

使用forall不在最外面的位置,你偶然发现了rank N types。内部forall上的b表示它必须是不透明的,多态的,与b类型的其他用法无关。这可能不是你想要做的。

这与词汇范围的类型变量略有不同,它也可以由最外层位置的forall引入,described here

通过删除(我认为)错误的forall在非最外层的位置,您将获得更简单的类型错误。