作为语法运算符的反引号

时间:2017-12-02 18:48:14

标签: haskell

刚遇到一些对我来说很奇怪的事情。反引号的功能类似于语法运算符。

applyOp :: Int -> (Int -> Int -> Int) -> Int -> Int
applyOp x op y = x `op` y

>  applyOp 2 (+) 5
7

我很惊讶地看到这一点。我一直想象反叛者需要包围操作符号或标识符,而不是可以在执行期间绑定到操作员的标识符。我是否以错误的方式思考这个问题?

1 个答案:

答案 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