Теперь, когда у вас появилось хотя бы смутное представление о том, что такое монады, давайте внесём в это представление несколько большую определённость. К великому удивлению, тип >Maybe
является монадой. Здесь мы исследуем её чуть лучше, чтобы понять, как она работает в этой роли.
ПРИМЕЧАНИЕ. Убедитесь, что вы в настоящий момент понимаете, что такое аппликативные функторы (мы обсуждали их в главе 11). Вы должны хорошо разбираться в том, как работают различные экземпляры класса >Applicative
и какие виды вычислений они представляют. Для понимания монад вам понадобится развить уже имеющиеся знания об аппликативных функторах.
Значение типа >Maybe a
представляет значение типа >a
, но с прикреплённым контекстом возможной неудачи в вычислениях. Значение >Just "дхарма"
означает, что в нём имеется строка >"дхарма"
. Значение >Nothing
представляет отсутствие значения, или, если вы посмотрите на строку как на результат вычисления, это говорит о том, что вычисление завершилось неуспешно.
Когда мы рассматривали тип >Maybe
как функтор, мы видели, что если нам нужно отобразить его с помощью функции, используя метод >fmap
, функция отображала содержимое, если это значение >Just
. В противном случае сохранялось значение >Nothing
, поскольку с помощью функции нечего отображать!
>ghci> fmap (++"!") (Just "мудрость")
>Just "мудрость!"
>ghci> fmap (++"!") Nothing
>Nothing
Тип >Maybe
функционирует в качестве аппликативного функтора аналогично. Однако при использовании аппликативных функторов сама функция находится в контексте наряду со значением, к которому она применяется. Тип >Maybe
является аппликативным функтором таким образом, что когда мы используем операцию ><*>
для применения функции внутри типа >Maybe
к значению, которое находится внутри типа >Maybe
, они оба должны быть значениями >Just
, чтобы результатом было значение >Just
; в противном случае результатом будет значение >Nothing
. Это имеет смысл. Если недостаёт функции либо значения, к которому вы её применяете, вы не можете ничего получить «из воздуха», поэтому вы должны распространить неудачу.
>ghci> Just (+3) <*> Just 3
>Just 6
>ghci> Nothing <*> Just "алчность"
>Nothing
>ghci> Justord <*> Nothing
>Nothing
Использование аппликативного стиля, чтобы обычные функции работали со значениями типа >Maybe
, действует аналогичным образом. Все значения должны быть значениями >Just
; в противном случае всё это напрасно (>Nothing
)!
>ghci> max <$> Just 3 <*> Just 6
>Just 6
>ghci> max <$> Just 3 <*> Nothing
>Nothing
А теперь давайте подумаем над тем, как бы мы использовали операцию