"中缀"如何运作?

And*_*man 14 haskell infix-notation

我在玩同infixr,infixlinfix声明.我知道如何infixrinfixl工作原理:

-- Test expression: 40 +++ 20 +++ 50 +++ 10 * 10

-- infixr 8 +++ -- Calculated as: (40 +++ (20 +++ (50 +++ 10))) * 10. Result: 630.
-- infixl 8 +++ -- Calculated as: (((40 +++ 20) +++ 50) +++ 10) * 10. Result: 800.

-- infixr 6 +++ -- Calculated as: 40 +++ (20 +++ (50 +++ (10 * 10))). Result: 75.
-- infixl 6 +++ -- Calculated as: ((40 +++ 20) +++ 50) +++ (10 * 10). Result: 125.

(+++) :: Int -> Int -> Int
a +++ b = a + (b `div` 2)
Run Code Online (Sandbox Code Playgroud)

但我不明白该infix关键字的工作原理.我是否正确地认为infix你总是需要用括号指定顺序?如果是这样,为什么数字参数必须考虑括号具有最高优先级?

Sho*_*hoe 30

TL;博士

rl参考相关性,您指定的号码是指运算符优先级.如果不指定关联性,则会得到一个只能通过显式括号关联的运算符,或者当关联性不具有模糊性时.

我们的测试数据结构

让我们使用数据结构来定义运算符并理解关联性如何工作:

data Test = Test String deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

它将包含使用以下运算符构建的字符串.

关联性与infixrinfixl

现在让我们定义右关联运算符和左关联运算符:

(>:) :: Test -> Test -> Test
(Test a) >: (Test b) = Test $ "(" ++ a ++ " >: " ++ b ++ ")"

(<:) :: Test -> Test -> Test
(Test a) <: (Test b) = Test $ "(" ++ a ++ " <: " ++ b ++ ")"

infixr 6 >:
infixl 6 <:
Run Code Online (Sandbox Code Playgroud)

这些运算符将通过将括号显式添加到关联的术语来构造结果运算符的字符串.

如果我们测试它,我们看到它正常工作:

print $ (Test "1") >: (Test "2") >: (Test "4")
-- Test "(1 >: (2 >: 4))"

print $ (Test "1") <: (Test "2") <: (Test "4")
-- Test "((1 <: 2) <: 4)"
Run Code Online (Sandbox Code Playgroud)

与"交往" infix

一个infix声明没有指定关联性.那么在那些情况下会发生什么呢?让我们来看看:

(?:) :: Test -> Test -> Test
(Test a) ?: (Test b) = Test $ "(" ++ a ++ " ?: " ++ b ++ ")"

infix 6 ?:
Run Code Online (Sandbox Code Playgroud)

然后让我们尝试一下:

print $ (Test "1") ?: (Test "2") ?: (Test "4")
Run Code Online (Sandbox Code Playgroud)

Woops,我们得到:

优先解析错误不能在同一个中缀表达式中混合`?:'[infix 6]和`?:'[infix 6]

正如您所看到的,语言解析器注意到我们没有指定运算符的关联性,也不知道该怎么做.

如果我们改为删除最后一个术语:

print $ (Test "1") ?: (Test "2")
-- Test "(1 ?: 2)"
Run Code Online (Sandbox Code Playgroud)

然后编译器不会抱怨.

要修复原始术语,我们需要明确添加括号; 例如:

print $ (Test "1") ?: ((Test "2") ?: (Test "4"))
-- Test "(1 ?: (2 ?: 4))"
Run Code Online (Sandbox Code Playgroud)

Live demo


Ry-*_*Ry- 5

因为

1 +++ 2 < 3
Run Code Online (Sandbox Code Playgroud)

工作良好.

  • @toraritte:问题:“如果是这样,考虑到括号具有最高优先级,为什么需要数字参数?” 下面是一个不带括号的表达式的示例,因此要求运算符具有优先级。它简短而切题。如果您觉得它没有帮助,那么,这完全在您的权利范围内。 (2认同)