. Вот классно!.. Если какое-либо из значений, которые мы пытаемся извлечь, равно
>Nothing, всё выражение
>do в результате вернёт значение
>Nothing. Мы выдёргиваем наружу их значения (если таковые существуют) и перекладываем необходимость беспокойства о контексте, идущем с этими значениями, на плечи оператора
>>>=.
Выражения >do – это просто другой синтаксис для сцепления монадических значений.
В выражении >do каждая строка, не являющаяся строкой >let, является монадическим значением. Чтобы просмотреть её результат, мы используем символ ><–. Если у нас есть значение типа >Maybe String и мы привязываем её к образцу с помощью символа ><–, этот образец будет иметь тип >String так же, как когда мы использовали операцию >>>= для передачи монадических значений анонимным функциям.
Последнее монадическое значение в выражении >do – такое как >Just (show x ++ y) в этом примере – не может быть использовано с символом ><– для привязки его результата, потому что если бы мы преобразовали выражение >do обратно в цепочку применений оператора >>>=, это не имело бы смысла. Наоборот, результат последнего выражения является результатом всего склеенного монадического значения, учитывая возможную неудачу вычисления каждого из предыдущих монадических значений. Рассмотрите, например, следующую строку:
>ghci> Just 9 >>= (\x –> Just (x > 8))
>Just True
Поскольку левым параметром функции >>>= является значение в конструкторе >Just, анонимная функция применяется к значению >9, и результатом становится значение >Just True. Мы можем переписать это в нотации >do следующим образом:
>marySue :: Maybe Bool
>marySue = do
> x <– Just 9
> Just (x > 8)
Сравнивая оба варианта, легко увидеть, почему результатом всего монадического значения является результат последнего монадического значения в выражении >do со всеми предыдущими монадическими значениями, сцепленными с ним.
Инструкция нашего канатоходца может также быть выражена с использованием нотации >do. Функции >landLeft и >landRight принимают количество птиц и шест и производят шест, обёрнутый в >Just. Исключение – это когда канатоходец соскальзывает, и тогда возвращается значение >Nothing. Мы использовали операцию >>>= для сцепления последовательных шагов, потому что каждый из них зависел от предыдущего и каждый обладал добавленным контекстом возможной неудачи. Здесь две птицы приземляются с левой стороны, затем две птицы – с правой, а потом одна птица – снова с левой:
>routine :: Maybe Pole
>routine = do
> start <– return (0, 0)
> first <– landLeft 2 start
> second <– landRight 2 first