函数应用程序编译错误

时间:2017-02-18 22:42:29

标签: haskell

我正在尝试学习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错了?

2 个答案:

答案 0 :(得分:5)

如果f f有效,那么f的类型是什么?

我们正在将f应用于参数,因此f必须是一个函数:f :: a -> b适用于某些类型ab

我们应用函数的论点是f,因此其类型必须为af :: a(即我们有(f :: a -> b) (f :: a))。< / p>

因为这两个f相同,所以我们得到a -> b = a。如果aa -> b相同,那么我们可以替换a,而a -> b(a -> b) -> b相同,这与{{1}相同等等。

这种扩张永远不会结束,这就是为什么ghc抱怨((a -> b) -> b) -> b有一个&#34;无限类型&#34;。

答案 1 :(得分:3)

f f x表示您要将fx传递给f

您需要确保首先评估f x,因此只有1个参数传递给最左侧的f

您可以通过将其包装在您发现的括号中,或者使用应用程序运算符(在这种情况下两者都有效等效)来实现:

f (f x) 
f $ f x