52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 104

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 104

выражении не смотря на то, что мы не учитываем конкретное значение Nothing, мы учитываем, что если один

из аргументов частично определённой функции не определён, то не определено всё значение. Сравните с

результатом выполнения следующего выражения.

По той же причине в последнем выражении мы получили три копии первого списка. Так произошло

потому, что второй список содержал три элемента. К каждому из элементов была применена функция 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 можно применять специальные значения к обычным функциям одного аргу-