我刚刚开始学习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
答案 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 = (.) . (.)
您可以将合成运算符与其本身组合。