Haskell 的四则运算符可以写成 curry形式,做不全调用:
比如 + * / - 四个运算,调用时候需要加括号
Prelude> (+) 2 3
5
(2+) 表示一个函数将调用的参数加上2
Prelude> (2+) 3
5
乘法和加法完全一样。
除法稍微不一样,(/) 表示用 第一个参数除以第二个参数。
Prelude> (/) 6 3
2.0
(6/)为不全调用,返回一个函数,该函数将用6来除以调用的参数得到结果。
Prelude> (6/) 3
2.0
(/6)为不全调用,返回一个函数,该函数将调用的参数除以6,即相当于除法函数缺了第一个参数调用。
Prelude> (/6) 3
0.5
减号函数调用的顺序依然和前面一样,用3来减去2.
Prelude> (-) 3 2
1
(3-)为不全调用,返回一个函数,该函数将3减去调用的参数得到结果。
Prelude> (3-) 2
1
因为减号 (-)
同时也是负号,所以,如果要得到一个函数把参数减去3,怎么办?仿照除法写成 (-3)
肯定不行,因为-3
就是一个数,不是一个函数,所以得加括号,让减号(-)
成为函数:
Prelude> ((-) 3) 2
1
很明显,这个结果是 用 3-2
得到的,而不是我们期望的 2-3
其实 (3-)
== ((-) 3)
这两个函数是等价的,因为 (-) 3
相当于减号(-)函数的不全调用,再补全一个参数,就相当于 (-) 3 2
这样的调用,也即等价于: 3 - 2
所以要得到参数减3函数这样做不行,一种办法可以用flip函数来变换参数的位置:
Prelude> (flip (-) 3) 2
-1
还可以用Haskell提供的另外一个函数 subtract :
Prelude> (subtract 3) 2
-1
subtract
函数和减号不同,subtract
是用第二个参数减去第一个参数,和 减号(-)
刚好相反。比如上面的,(subtract n)
就刚好返回我们需要的函数:将调用的参数减去 n 。
但如果写成下面这样:
Prelude> (`subtract` 3) 2
1
用中缀来调用,则得到和 ((-) 3)
或者说 (3-)
等价的函数,因为subtract
是用第二个参数减第一个参数,所以:3 \
subtract` 2得到的结果应该为 2-3,而
(`subtract` 3)` 缺了第一个参数。
Prelude> (3 `subtract`) 2
-1
如果写成上面这样,就相当于缺了第二个参数调用,因为subtract函数是第二个参数减去第一个参数的,所以不应该写成中缀调用,这样徒增复杂度,而没任何帮助,所以大部分情况下用不到这个subtract函数,但做不全调用时候,可以用来生成让参数减去n的函数即 (subtract n)
。
如果要写减去3的函数,其实可以转换成 (+ (-3))
这样就可以了
Prelude> map (+ (-3)) [1..3]
[-2,-1,0]
或者可以简写成: -3+
这样就省略一个括号
Prelude> map (-3+) [1..3]
[-2,-1,0]
查询一下加号和减号的类型:
Prelude> :type (+)
(+) :: Num a => a -> a -> a
Prelude> :type (-)
(-) :: Num a => a -> a -> a
可以看到,虽然减号(-)
同时也是一个一元运算符,但查询到的结果其实是减法的函数,Haskell还有另外一个函数:negate
用来把一个数取负数:
Prelude> negate 3
-3
Prelude> negate (-3)
3
Prelude> :type negate
negate :: Num a => a -> a
这样就减号一元运算符的状态了,其实根本没有什么运算符,函数式语言吗?一切都是函数而已。