如果我们有一个表达式:
a $ b @ c
$
是一个左结合操作符,@
是右结合的。它们具有相同的优先级。
这个表达式是如何解析的呢?作为 (a $ b) @ c
还是 a $ (b @ c)
?
如果我们有一个表达式:
a $ b @ c
$
是一个左结合操作符,@
是右结合的。它们具有相同的优先级。
这个表达式是如何解析的呢?作为 (a $ b) @ c
还是 a $ (b @ c)
?
这是一个很好的问题。虽然Dipstick正确指出在许多语言中,运算符优先级和结合性是为了避免这样的问题而定义的,但有些语言可能会出现这种情况。
Haskell就是这样一种语言。它允许您定义自己的中缀运算符及其优先级(从0到9的整数)和结合性(左、右、非)。很容易创建您所描述的情景的前提条件:
infixl 5 $$
($$) :: Int -> Int -> Int
a $$ b = a + b
infixr 5 @@
(@@) :: Int -> Int -> Int
a @@ b = a * b
然后是情况本身:
uhoh = 1 $$ 2 @@ 3
这导致了以下错误信息:
Precedence parsing error
cannot mix `$$' [infixl 5] and `@@' [infixr 5] in the same infix expression
当然,Haskell的解决方案——使用解析错误来中止程序——并不是处理这个问题的唯一方法,但它确实是一个合理的方法。
有关在Haskell中进行操作符解析的更多信息,请参见Haskell报告的4.4.2节。在相同优先级的运算符中,要么全部是右结合,要么全部是左结合,因此问题不会出现。