我正在尝试学习haskell并且无法配置它,为什么以下代码片段无法编译:
*Uncurry> applyTwice f x = f f x
<interactive>:14:20: error:
• Occurs check: cannot construct the infinite type:
t ~ t -> t2 -> t1
• In the first argument of ‘f’, namely ‘f’
In the expression: f f x
In an equation for ‘applyTwice’: applyTwice f x = f f x
• Relevant bindings include
x :: t2 (bound at <interactive>:14:14)
f :: t -> t2 -> t1 (bound at <interactive>:14:12)
applyTwice :: (t -> t2 -> t1) -> t2 -> t1
(bound at <interactive>:14:1)
这没关系:
applyTwice f x = f (f x)
在haskell函数应用程序是左关联的,第一个代码片段将适用于:
(f f) x
为什么(f f) x
错了?
答案 0 :(得分:5)
如果f f
有效,那么f
的类型是什么?
我们正在将f
应用于参数,因此f
必须是一个函数:f :: a -> b
适用于某些类型a
,b
。
我们应用函数的论点是f
,因此其类型必须为a
:f :: a
(即我们有(f :: a -> b) (f :: a)
)。< / p>
因为这两个f
相同,所以我们得到a -> b = a
。如果a
与a -> b
相同,那么我们可以替换a
,而a -> b
与(a -> b) -> b
相同,这与{{1}相同等等。
这种扩张永远不会结束,这就是为什么ghc抱怨((a -> b) -> b) -> b
有一个&#34;无限类型&#34;。
答案 1 :(得分:3)
f f x
表示您要将f
和x
传递给f
。
您需要确保首先评估f x
,因此只有1个参数传递给最左侧的f
。
您可以通过将其包装在您发现的括号中,或者使用应用程序运算符(在这种情况下两者都有效等效)来实现:
f (f x)
f $ f x