результатом выполнения следующего выражения.
По той же причине в последнем выражении мы получили три копии первого списка. Так произошло
потому, что второй список содержал три элемента. К каждому из элементов была применена функция const
x, где x пробегает по элементам списка слева от ( <*).
Аналогичный метод есть и в классе Monad:
class
Monadm
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
= errors
Функция >>в классе Monad, которую мы прятали из-за символа композиции, является аналогом постоян-
ной функции в классе Monad. Она работает так же как и *>. Функция fail используется для служебных нужд
Haskell при выводе ошибок. Поэтому мы её здесь не рассматриваем. Для определения экземпляра класса
Monadдостаточно определить методы return и >>=.
Исторические замечания
Напрашивается вопрос. Зачем нам функции return и pure или *>и >>? Если вы заглянете в документа-
цию к модулю Control.Monad, то там вы найдёте функции liftM, liftM2, liftM3, которые выполняют те же
операции, что и аналогичные функции из модуля Control.Applicative.
Стандартные библиотеки устроены так, потому что класс Applicativeпоявился гораздо позже класса
Monad. И к появлению этого нового класса уже накопилось огромное число библиотек, которые рассчитаны
на прежние имена. Но в будущем возможно прежние классы будут заменены на такие классы:
class Functorf where
fmap ::(a ->b) ->f a ->f b
class Pointedf where
pure ::a ->f a
class( Functorf, Pointedf) => Applicativef where
( <*>) ::f (a ->b) ->f a ->f b
( *>)
::f a ->f b ->f b
( <*)
::f a ->f b ->f a
class Applicativef => Monadf where
( >>=) ::f a ->(a ->f b) ->f b
Функторы и монады | 99
6.5 Краткое содержание
В этой главе мы долгой обходной дорогой шли к понятию монады и функтора. Эти классы служат для
облегчения работы в мире специальных функций вида a ->m b, в категории Клейсли
С помощью класса Functorможно применять специальные значения к обычным функциям одного аргу-
мента:
class Functorf where
fmap ::(a ->b) ->f a ->f b
С помощью класса Applicativeможно применять специальные значения к обычным функциям любого
числа аргументов:
class Functorf => Applicativef where
pure
::a ->f a
<*>
::f (a ->b) ->f a ->f b
liftA
:: Applicativef =>(a ->b) ->f a ->f b
liftA2 :: Applicativef =>(a ->b ->c) ->f a ->f b ->f c
liftA3 :: Applicativef =>(a ->b ->c ->d) ->f a ->f b ->f c ->f d
...
С помощью класса Monadможно применять специальные значения к специальным функциям.
class Monadm where
return
::a ->m a
( >>=)
::m a ->(a ->m b) ->m b
Функция return является функцией id в мире специальных функций, а функция >>=является функцией
применения ( $), с обратным порядком следования аргументов. Вспомним также класс Kleisli, на примере
котором мы узнали много нового из жизни специальных функций:
class Kleislim where
idK
::a ->m a
( *>)
::(a ->m b) ->(b ->m c) ->(a ->m c)
Мы узнали несколько стандартных специальных функций:
Частично определённые функции
a -> Maybeb
data Maybea = Nothing | Justa
Многозначные функции
a ->[b]
data[a] = [] |a :[a]
6.6 Упражнения
В первых упражнениях вам предлагается по картинке специальной функции написать экземпляр классов
Читать дальше