函数应用于haskell中的参数太少

时间:2018-12-06 18:51:53

标签: haskell

我刚刚开始学习haskell,但无法解决此问题。有人可以告诉我为什么在以下代码中将g应用于过少的参数时会出错。

f :: Int -> Int
f first  = 5+first

g :: Int -> Int -> Int
g  first second = first+second


compute :: (Int -> Int) -> (Int -> Int -> Int) -> Int -> Int -> Int
compute f g x y = (f . g) x y

2 个答案:

答案 0 :(得分:8)

一个常见的错误是认为函数组合运算符.传递了“所需的任意数量的参数”。但是事实并非如此:它仅使一个参数通过。

所以当你写

(f . g) x y

您可能希望这意味着

f (g x y)

但这实际上意味着

f (g x) y

-即y作为第二个参数而不是f传递给g。哎呀!

答案 1 :(得分:5)

首先,查看f . g的定义:

f . g = \x -> f (g x)

然后我们可以扩展compute的定义,如下所示:

compute f g x y = (f . g) x y
                = (\z -> f (g z)) x y
                = (f (g x)) y
                = (5 + (g x)) y

g x : Int -> Int,因为没有Num实例,所以您不能将其添加到5。

问题是您希望将g应用于x y,然后将其结果传递到f。为此,您需要的不仅仅是简单的合成。最简单的写法是直接:

compute f g x y = f (g x y)

如果您的目标是更轻松一点,那么您就需要看一下构图:

compute f g = \x -> \y -> f (g x y)
            -- application is left-associative
            = \x -> \y -> f ((g x) y)
            -- def'n of (.)
            = \x -> f . (g x)
            -- eta abstraction
            = \x -> (\z -> f . z) (g x)
            -- def'n of an operator section
            = \x -> (f .) (g x)
            -- def'n of (.)
            = (f .) . g

如果您想完全无分,可以写

compute = (.) . (.)

您可以将合成运算符与其本身组合。