Читаем Учебник по Haskell полностью

Если класс 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

---------------------------------------------------

-- Функции с окружением

--

--

a -> Reader env b

data Reader env a = Reader (env -> a)

runReader :: Reader env a -> env -> a

runReader (Reader f) = f

instance Monad (Reader env) where

return a

= Reader $ const a

ma >>= mf

= Reader $ \env ->

let b = runReader ma env

in

runReader (mf b) env

---------------------------------------------------

-- Функции-накопители

--

--

Monoid msg => a -> Writer msg b

data Writer msg a = Writer (a, msg)

deriving (Show)

runWriter :: Writer msg a -> (a, msg)

runWriter (Writer f) = f

instance Monoid msg => Monad (Writer msg) where

return a

= Writer (a, mempty)

ma >>= mf

= Writer (c, msgA ‘mappend‘ msgF)

where (b, msgA) = runWriter ma

(c, msgF) = runWriter $ mf b

Я пропустил определения для экземпляров классов Functor и Applicative, их можно получить из экзем-

пляра для класса Monad с помощью стандартных функций liftM, return и ap из модуля Control.Monad.

Нам встретилась новая запись в экспорте модуля. Для удобства мы экспортируем модули

Control.Applicative, Control.Monad и Data.Monoid целиком. Для этого мы написали ключевое слово

module перед экспортируемым модулем. Теперь если мы в каком-нибудь другом модуле импортируем

модуль Types нам станут доступными все функции из этих модулей.

Мы определили экземпляры для Functor и Applicative с помощью производных функций класса Monad.

106 | Глава 7: Функторы и монады: примеры

7.1 Случайные числа

С помощью монады State можно имитировать случайные числа. Мы будем генерировать случайные числа

из интервала от 0 до 1 с помощью алгоритма:

nextRandom :: Double -> Double

nextRandom = snd . properFraction . (105.947 * )

Функция properFraction возвращает пару, которая состоит из целой части и остатка числа. Взяв второй

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных