Изучай Haskell во имя добра! (Липовача) - страница 226

в функцию >landLeft 2, результатом будет >Nothing, и неудача будет распространена:

>ghci> Nothing >>= landLeft 2

>Nothing

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

>ghci> return (0, 0) >>= landRight 2 >>= landLeft 2 >>= landRight 2

>Just (2,4)

Вначале мы использовали функцию >return, чтобы взять шест и обернуть его в конструктор >Just. Мы могли бы просто применить выражение >landRight 2 к значению >(0, 0) – это было бы то же самое, – но так можно добиться большего единообразия, используя оператор >>>= для каждой функции. Выражение >Just (0, 0) передаётся в функцию >landRight 2, что в результате даёт результат >Just (0, 2). Это значение в свою очередь передаётся в функцию >landLeft 2, что в результате даёт новый результат >(2, 2), и т. д.

Помните следующий пример, прежде чем мы ввели возможность неудачи в инструкции Пьера?

>ghci> (0, 0) -: landLeft 1 -: landRight 4 -: landLeft (-1) -: landRight (-2)

>(0,2)

Он не очень хорошо симулировал взаимодействие канатоходца с птицами. В середине его равновесие было нарушено, но результат этого не отразил. Давайте теперь исправим это, используя монадическое применение (оператор >>>=) вместо обычного:

>ghci> return (0, 0) >>= landLeft 1 >>= landRight 4 >>= landLeft (-1) >>= landRight (-2)

>Nothing

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

1. Функция >return помещает значение >(0, 0) в контекст по умолчанию, превращая значение в >Just (0, 0).

2. Происходит вызов выражения >Just (0, 0) >>= landLeft 1. Поскольку значение >Just (0, 0) является значением >Just, функция >landLeft 1 применяется к >(0, 0), что в результате даёт результат >Just (1, 0), потому что птицы всё ещё находятся в относительном равновесии.

3. Имеет место вызов выражения >Just (1, 0) >>= landRight 4, и результатом является выражение >Just (1, 4), поскольку равновесие птиц пока ещё не затронуто, хотя Пьер уже удерживается с трудом.

4. Выражение >Just (1, 4) передаётся в функцию >landLeft (–1). Это означает, что имеет место вызов >landLeft (–1) (1, 4). Теперь ввиду особенностей работы функции >landLeft в результате это даёт значение >Nothing, так как результирующий шест вышел из равновесия.

5. Теперь, поскольку у нас есть значение >Nothing, оно передаётся в функцию >landRight (–2), но так как это >Nothing, результатом автоматически становится