имеет тип
>(Monad m) => a –> m a
. Она принимает значение и помещает его в минимальный контекст по умолчанию, который по-прежнему содержит это значение. Другими словами, она принимает нечто и оборачивает это в монаду. Мы уже использовали функцию
>return
при обработке действий ввода-вывода (см. главу 8). Там она понадобилась для получения значения и создания фальшивого действия ввода-вывода, которое ничего не делает, а только возвращает это значение. В случае с типом
>Maybe
она принимает значение и оборачивает его в конструктор
>Just
.
ПРИМЕЧАНИЕ. Функция >return
ничем не похожа на оператор >return
из других языков программирования, таких как C++ или Java. Она не завершает выполнение функции. Она просто принимает обычное значение и помещает его в контекст.
Следующей функцией является >>>=
, или связывание. Она похожа на применение функции, но вместо того, чтобы получать обычное значение и передавать его обычной функции, она принимает монадическое значение (то есть значение с контекстом) и передаёт его функции, которая принимает обычное значение, но возвращает монадическое.
Затем у нас есть операция >>>
. Мы пока не будем обращать на неё большого внимания, потому что она идёт в реализации по умолчанию, и её редко реализуют при создании экземпляров класса >Monad
. Мы подробно рассмотрим её в разделе «Банан на канате».
Последним методом в классе типов >Monad
является функция >fail
. Мы никогда не используем её в нашем коде явно. Вместо этого её использует язык Haskell, чтобы сделать возможным неуспешное окончание вычислений в специальной синтаксической конструкции для монад, с которой вы встретитесь позже. Нам не нужно сейчас сильно беспокоиться по поводу этой функции.
Теперь, когда вы знаете, как выглядит класс типов >Monad
, давайте посмотрим, каким образом для типа >Maybe
реализован экземпляр этого класса!
>instance Monad Maybe where
> return x = Just x
> Nothing >>= f = Nothing
> Just x >>= f = f x
> fail _ = Nothing
Функция >return
аналогична функции >pure
, так что для работы с ней не нужно большого ума. Мы делаем то же, что мы делали в классе типов >Applicative
, и оборачиваем в конструктор >Just
. Операция >>>=
аналогична нашей функции >applyMaybe
. Когда мы передаём значение типа >Maybe a
нашей функции, то запоминаем контекст и возвращаем значение >Nothing
, если значением слева является >Nothing
. Ещё раз: если значение отсутствует, нет способа применить к нему функцию. Если это значение >Just
, мы берём то, что находится внутри, и применяем к этому функцию >f
.
Мы можем поиграть с типом >Maybe
как с монадой: