Ответ 1
ТЛ; др
Значения r
и l
относятся к ассоциативности, а указанное вами число относится к приоритету оператора. Когда вы не указываете ассоциативность, вы получаете оператор, который может быть связан только с помощью явных скобок или когда ассоциативность не является неоднозначной.
Наша тестовая структура данных
Давайте используем структуру данных, чтобы определить операторы и понять, как работает ассоциативность:
data Test = Test String deriving (Eq, Show)
Он будет содержать строку, созданную с помощью следующих операторов.
Ассоциативность с infixr
и infixl
Теперь давайте определим ассоциативные операторы right- и left-:
(>:) :: Test -> Test -> Test
(Test a) >: (Test b) = Test $ "(" ++ a ++ " >: " ++ b ++ ")"
(<:) :: Test -> Test -> Test
(Test a) <: (Test b) = Test $ "(" ++ a ++ " <: " ++ b ++ ")"
infixr 6 >:
infixl 6 <:
Эти операторы создадут строку результирующего оператора, явно добавив скобки к нашим связанным терминам.
Если мы проверим это, мы увидим, что это работает правильно:
print $ (Test "1") >: (Test "2") >: (Test "4")
-- Test "(1 >: (2 >: 4))"
print $ (Test "1") <: (Test "2") <: (Test "4")
-- Test "((1 <: 2) <: 4)"
"Ассоциативность" с infix
Объявление infix
не определяет ассоциативность. Так что же должно произойти в этих случаях? Давай посмотрим:
(?:) :: Test -> Test -> Test
(Test a) ?: (Test b) = Test $ "(" ++ a ++ " ?: " ++ b ++ ")"
infix 6 ?:
А потом давай попробуем это:
print $ (Test "1") ?: (Test "2") ?: (Test "4")
Woops, мы получаем:
Ошибка разбора приоритета не может смешивать '?:' [Infix 6] и '?:' [Infix 6] в одном и том же выражении infix
Как видите, анализатор языка заметил, что мы не указали ассоциативность оператора и не знаем, что делать.
Если вместо этого мы удалим последний член:
print $ (Test "1") ?: (Test "2")
-- Test "(1 ?: 2)"
Тогда компилятор не жалуется.
Чтобы исправить первоначальный термин, нам нужно явно добавить скобки; например:
print $ (Test "1") ?: ((Test "2") ?: (Test "4"))
-- Test "(1 ?: (2 ?: 4))"