Понимание ассоциативности оператора привязки монады в Haskell

#haskell #operators #bind #monads #operator-precedence

#haskell #операторы #привязка #монады #оператор-приоритет

Вопрос:

Я пытался понять, как работает оператор привязки монады, но нашел пример, который был странным, потому что кажущаяся ассоциативность не имела для меня смысла, учитывая тот факт, что >>= она является левоассоциативной. Вот пример, тестирование по подсказке интерпретатора:

 > Just 3 >>= x -> Just "!" >>= y -> Just (show x    y)
Just "3!"

> Just 3 >>= (x -> Just "!" >>= (y -> Just (show x    y)))
Just "3!"

> (Just 3 >>= x -> Just "!" )>>= y -> Just (show x    y)
<interactive>:3:50: error: Variable not in scope: x :: ()
  

Я этого не понимаю, потому что второй пример противоречит третьему, потому что кажется, что он идет по пути, который противоречит известной ассоциативности. Я знаю, что мне чего-то не хватает, но я не знаю, чего.

Комментарии:

1. Он связывается infixl , так же как и второе выражение.

Ответ №1:

Согласно правилу максимального Мунка, лямбды анализируются как можно дальше вправо, поэтому у левой ассоциативности >>= оператора нет шансов вступить в игру. Первый анализируется как ваш второй фрагмент, а не как третий (что, конечно, является недопустимым кодом).

Комментарии:

1. Это хорошо, я понятия не имел. Это означает, что лямбды всегда смогут переопределять приоритет оператора?

2. приоритет вступает в игру только позже. сначала лямбды считываются как можно дальше вправо, пока это не создает синтаксически неправильный код.

Ответ №2:

Это связано с тем, что скобки x выходят за рамки:

 (Just 3 >>= x -> Just "!" ) >>= y -> Just (show x    y)
  

(Just 3 >>= x -> Just "!" ) станет Just "!" и x выйдет за рамки.