52700.fb2
из аргументов частично определённой функции не определён, то не определено всё значение. Сравните с
результатом выполнения следующего выражения.
По той же причине в последнем выражении мы получили три копии первого списка. Так произошло
потому, что второй список содержал три элемента. К каждому из элементов была применена функция const
x, где x пробегает по элементам списка слева от (<*).
Аналогичный метод есть и в классе Monad:
class
Monad m
where
return
:: a -> m a
(>>=)
:: m a -> (a -> m b) -> m b
(>> )
:: m a -> m b -> m b
fail
:: String -> m a
m >> k
= m >>= const k
fail s
= error s
Функция >> в классе Monad, которую мы прятали из-за символа композиции, является аналогом постоян-
ной функции в классе Monad. Она работает так же как и *> . Функция fail используется для служебных нужд
Haskell при выводе ошибок. Поэтому мы её здесь не рассматриваем. Для определения экземпляра класса
Monad достаточно определить методы return и >>=.
Исторические замечания
Напрашивается вопрос. Зачем нам функции return и pure или *> и >> ? Если вы заглянете в документа-
цию к модулю Control.Monad, то там вы найдёте функции liftM, liftM2, liftM3, которые выполняют те же
операции, что и аналогичные функции из модуля Control.Applicative.
Стандартные библиотеки устроены так, потому что класс Applicative появился гораздо позже класса
Monad. И к появлению этого нового класса уже накопилось огромное число библиотек, которые рассчитаны
на прежние имена. Но в будущем возможно прежние классы будут заменены на такие классы:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Pointed f where
pure :: a -> f a
class (Functor f, Pointed f) => Applicative f where
(<*> ) :: f (a -> b) -> f a -> f b
(*> )
:: f a -> f b -> f b
(<*)
:: f a -> f b -> f a
class Applicative f => Monad f where
(>>=) :: f a -> (a -> f b) -> f b
Функторы и монады | 99
6.5 Краткое содержание
В этой главе мы долгой обходной дорогой шли к понятию монады и функтора. Эти классы служат для
облегчения работы в мире специальных функций вида a -> m b, в категории Клейсли
С помощью класса Functor можно применять специальные значения к обычным функциям одного аргу-