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

>Just 3

>ghci> Just 1 `applyMaybe` \x –> if x > 2 then Just x else Nothing

>Nothing

Результаты оказались такими, каких мы и ждали! Если монадическое значение слева равно >Nothing, то всё будет равно >Nothing. А если функция справа возвращает значение >Nothing, результатом опять будет >Nothing. Это очень похоже на тот случай, когда мы использовали тип >Maybe в качестве аппликативного функтора и в результате получали значение >Nothing, если где-то в составе присутствовало значение >Nothing.

Похоже, мы догадались, как взять причудливое значение, передать его функции, которая принимает обычное значение, и вернуть причудливое значение. Мы сделали это, помня, что значение типа >Maybe представляет вычисление, которое могло окончиться неуспешно.

Вы можете спросить себя: «Чем это полезно?» Может показаться, что аппликативные функторы сильнее монад, поскольку аппликативные функторы позволяют нам взять обычную функцию и заставить её работать со значениями, имеющими контекст. В этой главе вы увидите, что монады, будучи усовершенствованными аппликативными функторами, тоже способны на такое. На самом деле они могут делать и кое-какие другие крутые вещи, на которые не способны аппликативные функторы.

Мы вернёмся к >Maybe через минуту, но сначала давайте взглянем на класс типов, который относится к монадам.

Класс типов Monad

Как и функторы, у которых есть класс типов >Functor, и аппликативные функторы, у которых есть класс типов >Applicative, монады обладают своим классом типов: >Monad! (Ух ты, кто бы мог подумать?)

>class Monad m where

>   return :: a –> m a


>   (>>=) :: m a –> (a –> m b) –> m b


>   (>>) :: m a –> m b –> m b

>   x >> y = x >>= \_ –> y


>   fail :: String –> m a

>   fail msg = error msg

В первой строке говорится >class Monad m where. Стойте, не говорил ли я, что монады являются просто расширенными аппликативными функторами? Не надлежит ли здесь быть ограничению класса наподобие >class (Applicative m) => Monad m where, чтобы тип должен был являться аппликативным функтором, прежде чем он может быть сделан монадой? Ладно, положим, надлежит, – но когда появился язык Haskell, людям не пришло в голову, что аппликативные функторы хорошо подходят для этого языка. Тем не менее будьте уверены: каждая монада является аппликативным функтором, даже если в объявлении класса >Monad этого не говорится.



Первой функцией, которая объявлена в классе типов >Monad, является >return. Она аналогична функции >pure, находящейся в классе типов >Applicative. Так что, хоть она и называется по-другому, вы уже фактически с ней знакомы. Функция