米兰达类型错误

时间:2014-05-21 23:33:23

标签: haskell partial-application miranda

谁能告诉我哪里出错?

b f x = f x (f x)

我的理解是:因为左边的f有一个参数,但右边有两个参数?

更详细的解释?

2 个答案:

答案 0 :(得分:2)

让我们尝试构建该类型:

b :: ... ?

我们至少有两个参数,因此我们可以相应地更改b

b :: a -> c -> d

b的右侧表明f是一个函数。让我们首先关注第一个论点:

f :: c -> e

到目前为止,一切都很合适:list的第一个参数与b的第二个参数具有相同的类型。让我们继续在右边。

f x (f x)

如果我们采用f x _,我们必须假设ee :: k -> l,也就是说,我们采取另一个论点。我们现在有

f :: c -> k -> l

现在看一下f第二个参数的类型。它的类型应该是f x

的类型
f x :: k -> l

所以k = k -> l。这是一种无限类型,我们也可以通过查看ghci的错误消息来看到:

Prelude> let b f x = f x (f x)

<interactive>:2:18:
    Occurs check: cannot construct the infinite type: t1 = t1 -> t0
    In the return type of a call of `f'
    Probable cause: `f' is applied to too few arguments
    In the second argument of `f', namely `(f x)'
    In the expression: f x (f x)

类型检查器放弃,因为无法构造无限类型。最后,由于您对不同数量的参数应用f,因此会发生这种情况。

答案 1 :(得分:1)

编译器尝试推断f的类型。首先,它看到f采用参数x和另一个参数(f x),现在我们将其替换为y。因此,当编译器看到f x y之类的内容时,它会推断f的类型为a -> b -> cx :: ay :: bf x y :: c。然后它检查y更接近,看到它的类型更具体b -> c,因为它已经知道f必须有第二个参数。所以它现在可以确定b ~ b -> c。这就是它必须停止的地方,b怎么也可以b -> c?如果它继续替换b ~ b -> c,它将有一个无限递归试图找出b是什么类型!这显然无法工作,因此抛出一个编译错误,说它无法构造无限类型b = b -> c(注意:错误消息可能使用与bc不同的名称)。我得到的错误消息实际上非常有用:

Occurs check: cannot construct the infinite type: t1 = t1 -> t0
In the return type of a call of `f'
Probable cause: `f' is applied to too few arguments
In the second argument of `f', namely `(f x)'
In the expression: f x (f x)

这会告诉你问题的确切位置,即“(f x)”,并告诉你可能的原因“f适用于太少的参数”,说它“无法构造无限类型” t1 = t1 -> t0”。