1

谁能告诉我哪里出了问题?

b f x = f x (f x)

我的理解是:因为f左边有一个论点,而右边有两个论点?

有更详细的解释吗?

4

2 回答 2

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 的错误信息看到:

前奏>让bfx = fx(fx)

<交互式>:2:18:
    发生检查:无法构造无限类型:t1 = t1 -> t0
    在“f”调用的返回类型中
    可能的原因:“f”应用于太少的参数
    在`f'的第二个参数中,即`(fx)'
    在表达式中:fx (fx)

类型检查器放弃了,因为它不能构造无限类型。最后,这是因为您应用f了不同数量的参数。

于 2014-05-21T23:55:44.947 回答
1

编译器尝试推断f. 首先,它看到 thatf接受一个参数x和另一个参数(f x),现在我们将其替换为y。因此,当编译器看到类似 的内容时f x y,它会推断出f具有a -> b -> c、 with x :: ay :: b和的类型f x y :: c。然后它y更仔细地检查,发现它的类型更具体b -> c,因为它已经知道f必须有第二个参数。所以它现在可以确定b ~ b -> c。这就是它必须停止的地方,怎么可能bb -> c?如果它继续替换b ~ b -> c,它将有一个无限递归试图找出什么类型b是!这显然是行不通的,所以它会抛出一个编译错误,说它不能构造无限类型(注意:错误消息可能使用与orb = 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”。

于 2014-05-21T23:56:38.190 回答