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

Приступаем к типу Maybe

Теперь, когда у вас появилось хотя бы смутное представление о том, что такое монады, давайте внесём в это представление несколько большую определённость. К великому удивлению, тип >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

А теперь давайте подумаем над тем, как бы мы использовали операцию