刚刚遇到了一些对我来说似乎很奇怪的事情。反引号的功能类似于语法运算符。
applyOp :: Int -> (Int -> Int -> Int) -> Int -> Int
applyOp x op y = x `op` y
> applyOp 2 (+) 5
7
Run Code Online (Sandbox Code Playgroud)
看到这一点我很惊讶。我一直认为需要反引号来包围运算符符号或标识符,而不是可以在执行期间绑定到运算符的标识符。我是否以错误的方式思考这个问题?
反引号是将标识符转换为中缀运算符的语法糖。也就是说,a `f` b = f a b是一般的重写规则。这对于清晰起见很有用,但也可以避免太多括号,因为f (a b) (c d)可以重写为a b `f` c d.
然而,使用这些有一些注意事项,但只有两个限制:
反引号表达式必须是标识符,因此1 `mod` 2有效,但a `zipWith (+)` b无效,因为它涉及函数应用。
只有字母数字标识符可以反引号,因此1 `mod` 2有效,但1 `(+)` 2无效。您可以将此视为先前限制的应用。
反引号表达式的优先级为 9,并且是左关联的,因此a `f` b `f` c被解析为(a `f` b) `f` c,并且一般其他运算符会包含它,因此a +
c `f` b被解析为a + (c `f` b)*
在这种情况下,applyOp x op y = x `op` y是有效的,因为op是一个字母数字标识符,这相当于applyOp x op y = op x y。请注意,绑定模式匹配标识符没有限制!
*这对于标准 Prelude 运算符!!和来说是不正确的.。有关优先级和固定性的更多信息可以在Haskell 98 报告中找到。