Считайте, что списки являются частными случаями деревьев. В этом смысле деревья будут описывать
многозначные функции, которые возвращают несколько значений, организованных в иерархическую струк-
туру.
Стандартные функции
Почитайте документацию к модулям Control.Monad и Control.Applicative. Присмотритесь к функциям,
попробуйте применить их в интерпретаторе.
Эквивалентность классов Kleisli и Monad
Покажите, что классы Kleisli и Monad эквивалентны. Для этого нужно для произвольного типа c с одним
параметром m определить два экземпляра:
instance Kleisli m => Monad
m where
instance Monad
m => Kelisli m where
Нужно определить экземпляр одного класса с помощью методов другого.
Свойства класса Monad
Если класс Monad эквивалентен Kleisli, то в нём должны выполнятся точно такие же свойства. Запишите
свойства класса Kleisli через методы класса Monad
104 | Глава 6: Функторы и монады: теория
Глава 7
Функторы и монады: примеры
В этой главе мы закрепим на примерах то, что мы узнали о монадах и функторах. Напомню, что с по-
мощью монад и функторов мы можем комбинировать специальные функции вида (a -> m b) с другими
специальными функциями.
У нас есть функции тождества и применения:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor f => Applicative f where
pure
:: a -> f a
(<*> )
:: f (a -> b) -> f a -> f b
class Monad m where
return
:: a -> m a
(>>=)
:: m a -> (a -> m b) -> m b
(=<< ) :: (a -> m b) -> m a -> m b
(=<< ) = flip (>>=)
Вспомним основные производные функции для этих классов:
Или в терминах класса Kleisli:
-- Композиция
(>=> ) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
(<=< ) :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c)
-- Константные функции
(*> ) :: Applicative f => f a -> f b -> f b
(<*) :: Applicative f => f a -> f b -> f a
-- Применение обычных функций к специальным значениям
(<$> )
:: Functor f => (a -> b) -> f a -> f b
liftA
:: Applicative f => (a -> b)
-> f a -> f b
liftA2 :: Applicative f => (a -> b -> c)
-> f a -> f b -> f c
liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
-- Преобразование элементов списка специальной функцией
mapM
:: Monad m => (a -> m b) -> [a] -> m [b]
Нам понадобится модуль с определениями типов и экземпляров монад для всех типов, которые мы рас-
смотрели в предыдущей главе. Экземпляры для [] и Maybe уже определены в Prelude, а типы State, Reader
и Writer можно найти в библиотеках mtl и transformers. Пока мы не знаем как устанавливать библиотеки
определим эти типы и экземпляры для Monad самостоятельно. Возможно вы уже определили их, выполняя
одно из упражнений предыдущей главы, если это так сейчас вы можете сверить ответы. Определим модуль
Types:
module Types(
State(.. ), Reader(.. ), Writer(.. ),
runState, runWriter, runReader,
| 105
module Control.Applicative,
module Control.Monad,
module Data.Monoid)
where
import Data.Monoid
import Control.Applicative
import Control.Monad
-------------------------------------------------
-- Функции с состоянием
--
--
a -> State s b
data State s a = State (s -> (a, s))
runState :: State s a -> s -> (a, s)
runState (State f) = f
instance Monad (State s) where
return a
= State $ \s -> (a, s)
ma >>= mf = State $ \s0 ->
let (b, s1) = runState ma s0
in
runState (mf b) s1
---------------------------------------------------
-- Функции с окружением
--