谁能告诉我哪里出了问题?
b f x = f x (f x)
我的理解是:因为f
左边有一个论点,而右边有两个论点?
有更详细的解释吗?
谁能告诉我哪里出了问题?
b f x = f x (f x)
我的理解是:因为f
左边有一个论点,而右边有两个论点?
有更详细的解释吗?
让我们尝试构造该类型:
b :: ... ?
我们至少有两个参数,所以让我们b
相应地改变:
b :: a -> c -> d
的右侧b
表明这f
是一个函数。让我们首先只关注第一个参数:
f :: c -> e
到目前为止,一切都很好:list 的第一个参数与 b 的第二个参数具有相同的类型。让我们继续右手边。
f x (f x)
如果我们取f x _
,我们必须假设e
是e :: 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
了不同数量的参数。
编译器尝试推断f
. 首先,它看到 thatf
接受一个参数x
和另一个参数(f x)
,现在我们将其替换为y
。因此,当编译器看到类似 的内容时f x y
,它会推断出f
具有a -> b -> c
、 with x :: a
、y :: b
和的类型f x y :: c
。然后它y
更仔细地检查,发现它的类型更具体b -> c
,因为它已经知道f
必须有第二个参数。所以它现在可以确定b ~ b -> c
。这就是它必须停止的地方,怎么可能b
呢b -> c
?如果它继续替换b ~ b -> c
,它将有一个无限递归试图找出什么类型b
是!这显然是行不通的,所以它会抛出一个编译错误,说它不能构造无限类型(注意:错误消息可能使用与orb = b -> c
不同的名称)。我收到的错误消息实际上很有帮助:b
c
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
”。