我可能会问一些非常愚蠢的事情,答案可能非常简单,因为“实施者选择了那种方式”,但我在这里。
要添加两个数字,我们可以使用任何样式:(10+) 4
或10 + 4
或(10 + 4)
。
如果我们有两个功能,请说add10
和multiply5
然后把它们组成一个函数,比如说add10andMultiply5
然后
add10.mul5 10
似乎在出现错误时发出错误
add10.mul5 $ 5
将起作用
(add10.mul5) 5
将起作用
add10andMultiply5 5
也会奏效。
为什么第一个不应该工作的任何评论? 请赐教。感谢。
答案 0 :(得分:7)
这是一个优先问题,或者不同操作的紧密程度。
在Haskell中,函数应用程序具有最高优先级(最严格的绑定),其次是函数组合,然后是$
的函数应用程序。它有点像算术,其中取幂具有最高优先级,然后乘法,然后加法,以便
1 + 2 ^ 4 * 3 + 4 * 3
被解析为
1 + ((2 ^ 4) * 3) + (4 * 3)
在您的示例中,您有
add10 . mul5 10
将被解析为
add10 . (mul5 10)
因为函数应用程序绑定最紧密。这不起作用,因为mul5 10
是一个数字而add10
是一个函数,并且合成只在两个函数之间起作用。
另一方面,
add10 . mul5 $ 10
被解析为
(add10 . mul5) $ 10
因为函数组合的优先级高于$
的应用程序。
答案 1 :(得分:4)
Haskell中的功能组合优先于函数应用程序。因此add10.mul5 10
被解析为add10 . (mul5 10)
。现在,.
的类型为:
(.) :: (b -> c) -> (a -> b) -> a -> c
第一个参数(add10
)的类型为Int -> Int
,因此我们可以确定b为Int
,因此.
期望其第二个参数为a -> Int
{1}}。但它的类型为Int
。添加$
会更改关联,这意味着在将组合函数应用到10之前完成函数组合。
一切都在你的第一个例子中起作用,因为你没有编写功能,你只是应用它们。在这种情况下,等价物将尝试(10+) . 4
,您将观察到它也会失败。