刚遇到一些对我来说很奇怪的事情。反引号的功能类似于语法运算符。
applyOp :: Int -> (Int -> Int -> Int) -> Int -> Int
applyOp x op y = x `op` y
> applyOp 2 (+) 5
7
我很惊讶地看到这一点。我一直想象反叛者需要包围操作符号或标识符,而不是可以在执行期间绑定到操作员的标识符。我是否以错误的方式思考这个问题?
答案 0 :(得分:3)
反引号是语法糖,可将标识符转换为中缀运算符。也就是说,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
。请注意,绑定模式匹配标识符存在 no 限制!
*这对于标准Prelude运算符!!
和.
来说是不正确的。有关优先级和固定性的更多信息,请参阅The Haskell 98 Report。