关于 haskell 的.和$运算符
函数应用是左结合的且优先级最高,然后是.
运算符,最后是$
运算符。
所以对表达式——
1 |
|
首先是 map 进行调用,其以 product 为参数——
1 |
|
这里,假设$先调用,则会变成这样的结果——
1 |
|
这显然是离谱的,因此,.
将首先调用,形成这样的结果——
1 |
|
Bingo!
在这里,$
运算符的意义在于,避免最靠近参数的函数直接计算出了结果,而是延迟到计算结果的前一刻(也就是得到以输入参数为唯一参数的函数),待.
运算符将各个函数组合后再进行真正的运算。
可以认为,$把原表达式变成这样了——
1 |
|
这或许是对该运算符的最容易理解的诠释。
用 kotlin 的话来说,它代表这样的链式调用——
1 |
|
如果最近的函数的入参有多个怎么办?考虑$
的签名:($) :: (a -> b) -> a -> b
,其左边应该是函数,右边应该是参数,事情变得明了起来了——将$
加到最后一个参数前面,比如下面的示例,它定义了一个获取坐标到原点距离的函数——
1 |
|
我觉得这在代码结构上实在不太优雅,但或许之后会有改变。转换成 Kotlin,对distance 3 4
,即sqrt . squareSum 3 $ 4
,有这样的等价代码——
1 |
|
对参数是表达式的情况,也可以使用$
来减少括号——
1 |
|
因为$
最低的优先级,3+4+5
将被先计算。当然,这特性可无法用在fib (n - 1) + fib (n - 2)
中。
顺带一提,.
运算符的签名如下,可见其组合的函数必须是接受单参数的,且最终组合的函数,接受参数为最内的函数的参数的类型,返回结果为最外的函数的返回值的类型。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!