Haskell 的四则运算符

2016-04-20  本文已影响0人  jsk

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

这样就减号一元运算符的状态了,其实根本没有什么运算符,函数式语言吗?一切都是函数而已。

上一篇下一篇

猜你喜欢

热点阅读