运算符#
总览#
Haskell 中,所有运算符本质上均为函数,在 GHCi 中使用
:type命令检查运算符类型时,须用小括号()包围;(+) :: Num a => a -> a -> a
Haskell 中,所有运算符都默认为中缀运算符,即参数分布在左右两侧,小括号
()可以将运算符转换为前缀函数;res1 = 2 + 3 -- 5 res2 = (+) 2 3 -- 5
Haskell 中,使用一对反引号可将接受两个参数的函数转换为中缀运算符,此时左运算子作为第一个位置参数传入;
addFunc :: Integer -> Integer -> Integer -- 函数定义 addFunc x y = x + y res1 = addFunc 1 2 res2 = 1 `addFunc` 2 res1 == res2 -- True
算术运算符#
| 运算符 | 说明 |
|---|---|
+ |
加 |
- |
减 |
* |
乘 |
/ |
除(浮点) |
quot |
除(向零取整) |
div |
除(向负取整) |
mod |
取模 |
rem |
取余 |
^ |
幂(整幂) |
^^ |
幂(浮点底整幂) |
** |
幂(浮点底浮点幂) |
/:两侧只接受浮点数为参数,否则报错;i :: Integer i = 3 x = i / i -- The type signature for ‘i’ lacks an accompanying binding
div和mod:Haskell 中整除和取模没有对应运算符,但有对应函数;x = (-7) `mod` 3 -- 2 y = 3 `div` 2 -- 1
^右侧只接受整数,^^左侧接受浮点数,右侧接受整数,**两侧只接受浮点数;Haskell 中,任何时候负数都必须用括号包围,否则会识别为减号;
z = (-3) * (-7) -- returns 21 z = -3 * -7 -- Precedence parsing error -- cannot mix ‘*’ [infixl 7] and prefix `-' [infixl 6] -- in the same infix expression
所有运算符两侧(除幂运算)必须为同一数值数据类型,Haskell 不作隐式类型转换;
j :: Float k :: Double j = 3.2 k = 3.2 l = j + k -- Couldn't match expected type ‘Float’ with actual type ‘Double’
逻辑运算符#
| 运算符 | 说明 |
|---|---|
&& |
逻辑与 |
|| |
逻辑或 |
not |
逻辑非 |
谓词:
可进行真值判断的表达式,且该表达式决定是否执行后续操作;
res1 = if "Haskell" > "C++" -- 谓词 then 3 else 4
在函数参数的类型声明中,若该函数第一个参数为一个返回布尔值的函数,则该函数也称为谓词;
res1 = True && False
res2 = not (False || True)
比较运算符#
| 运算符 | 说明 |
|---|---|
== |
等于 |
/= |
不等于 |
> |
大于 |
< |
小于 |
<= |
大于或等于 |
>= |
小于或等于 |
与其他语言不同,Haskell 使用
/=作为不等于;当比较运算符两侧为字符时,比较字符的 Unicode 码,若为字符串,则从左向右依次比较;
当比较运算符两侧为列表时,从左至右依次对每个元素进行比较(若均相对,则元素更多者更大);
res = [3,4,2] > [3,4] -- True
固定性声明#
固定性:即运算符的优先级,在 Haskell 中分为 0~9 共 10 个等级,数字越大运算优先级越高;
结合性:Haskell 中分为左结合、右结合和无结合三种;
- 左结合:首先与左运算子运算;
- 右结合:首先与右运算子运算;
- 无结合:不结合;
infix*关键字:infix <fixity> <operator> infixl <fixity> <operator> infixr <fixity> <operator>
infix:指定无结合运算符的固定性;infixl:指定左结合运算符的固定性;infixr:指定右结合运算符的固定性;infix*关键字同样可以定义中缀函数的固定性;
运算符命名:除少数保留字外,Haskell 中的运算符可以用任意非标识符字符定义;
- 合法字符:
!#$%&*+./=<?>@\~ˆ-:; - 保留字:
..、:、::、=、\、|、<-、->、@、~和=>;
- 合法字符:
infixl 6 -?+
(-?+) :: (Num a, Ord a) => a -> a -> a
x -?+ y | x > y = x - y
| otherwise = x + y
exp1 = 3 -?+ 2 -- 1
exp2 = 3 -?+ 4 -- 7
exp3 = 3 -?+ 2 -?+ 5 -- 6
内置运算符#
| 优先级 | 左结合 | 无结合 | 右结合 |
|---|---|---|---|
| 9 | !! |
. |
|
| 8 | ^, ^^, ** |
||
| 7 | *, /, div, mod, rem, quot |
||
| 6 | +, - |
||
| 5 | :, ++ |
||
| 4 | ==, /=, <, <=, >, >=, elem, notElem |
||
| 3 | && |
||
| 2 | || |
||
| 1 | >>, >>= |
||
| 0 | $, $!, seq |