我可能会问一些非常愚蠢的问题,答案可能很简单,比如"实现者选择了那样的方式",但现在我开始了。
要添加两个数字,我们可以使用任何样式:(10+) 4
、10 + 4
或(10 + 4)
。
而如果我们有两个函数,比如add10
和multiply5
并将它们组合成一个函数,比如add10andMultiply5
然后add10.mul5 10
似乎在
时出错add10.mul5 $ 5
将工作并且(add10.mul5) 5
将工作并且add10andMultiply5 5
也会起作用。
有什么意见为什么第一个不应该起作用吗?请开导我。谢谢。
这是一个优先级问题,或者不同操作绑定的紧密程度。
在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
因为函数组合比使用CCD_ 14的应用具有更高的优先级。
Haskell中的函数组合的优先级低于函数应用程序。因此CCD_ 15被解析为CCD_。现在,.
的类型被给出为:
(.) :: (b -> c) -> (a -> b) -> a -> c
第一个自变量(add10
)的类型为Int -> Int
,因此我们可以确定b是Int
,因此.
期望其第二个自变量的类型为a -> Int
。但它的类型却是Int
。添加$
会更改关联,这意味着在将组成的函数应用于10之前完成函数组合。
在第一个例子中,一切都正常,因为你不是在编写函数,你只是在应用它们。在这种情况下,等效的方法是尝试执行(10+) . 4
,您会发现它也会失败。