And*_*man 14 haskell infix-notation
我在玩同infixr,infixl和infix声明.我知道如何infixr和infixl工作原理:
-- 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
在r与l参考相关性,您指定的号码是指运算符优先级.如果不指定关联性,则会得到一个只能通过显式括号关联的运算符,或者当关联性不具有模糊性时.
让我们使用数据结构来定义运算符并理解关联性如何工作:
data Test = Test String deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)
它将包含使用以下运算符构建的字符串.
infixr和infixl现在让我们定义右关联运算符和左关联运算符:
(>:) :: 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)
因为
1 +++ 2 < 3
Run Code Online (Sandbox Code Playgroud)
工作良好.