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

Аппликативный функтор Maybe

Давайте взглянем на реализацию экземпляра класса >Applicative для типа >Maybe:

>instance Applicative Maybe where

>   pure = Just

>   Nothing <*> _ = Nothing

>   (Just f) <*> something = fmap f something

Опять же из определения класса мы видим, что идентификатор >f, который играет роль аппликативного функтора, должен принимать один конкретный тип в качестве параметра. Поэтому мы пишем >instance Applicative Maybe where вместо >instance Applicative (Maybe a) where.

Далее, у нас есть функция >pure. Вспомните, что функция должна что-то принять и обернуть в аппликативное значение. Мы написали >pure = Just, потому что конструкторы данных вроде >Just являются обычными функциями. Также можно было бы написать >pure x = Just x.

Наконец, у нас есть определение оператора ><*>. Извлечь функцию из значения >Nothing нельзя, поскольку внутри него нет функции. Поэтому мы говорим, что если мы пробуем извлечь функцию из значения >Nothing, результатом будет то же самое значение >Nothing.

В определении класса >Applicative есть ограничение класса >Functor – значит, мы можем считать, что оба параметра оператора ><*> являются значениями функтора. Если первым аргументом выступает не значение >Nothing, а >Just с некоторой функцией внутри, то мы говорим, что с помощью данной функции хотим отобразить второй параметр. Этот код также заботится о случае, когда вторым аргументом является значение >Nothing, потому что его отображение с помощью любой функции при использовании метода >fmap вернёт всё то же >Nothing. Итак, в случае с типом >Maybe оператор ><*> извлекает функцию из значения слева, если это >Just, и отображает с её помощью значение справа. Если какой-либо из параметров является значением >Nothing, то и результатом будет >Nothing.

Теперь давайте это опробуем:

>ghci> Just (+3) <*> Just 9

>Just 12

>ghci> pure (+3) <*> Just 10

>Just 13

>ghci> pure (+3) <*> Just 9

>Just 12

>ghci> Just (++"ха-ха") <*> Nothing Nothing

>ghci> Nothing <*> Just "во-от"

>Nothing

Вы видите, что выполнение выражений >pure (+3) и >Just (+3) в данном случае – одно и то же. Используйте функцию >pure, если имеете дело со значениями типа >Maybe в аппликативном контексте (если вы используете их с оператором ><*>); в противном случае предпочитайте конструктор >Just.

Первые четыре введённых строки демонстрируют, как функция извлекается, а затем используется для отображения; но в данном случае этого можно было добиться, просто применив не обёрнутые функции к функторам. Последняя строка любопытна тем, что мы пытаемся извлечь функцию из значения >Nothing, а затем отображаем с её помощью нечто, что в результате даёт