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

Если присмотреться к типам функций, можно понять, что тип-экземпляр cat принимает два параметра.

Совсем как тип функции (a -> b). Формально его можно записать в префиксной форме так (-> ) a b.

Получается, что тип cat это что-то вроде функции. Это некоторые сущности, у которых есть понятия

тождества и композиции.

Для обычных функций экземпляр класса Category уже определён. Но в этом модуле у нас есть ещё и

необычные функции, функции которые преобразуют ленты значений. Функции id и (. ) мы определим,

сделав наш тип St экземпляром класса Category. Также определите постоянный преобразователь. Он

на любой вход возвращает одно и то же число, и преобразователь, который будет накапливать сумму

поступающих на вход значений, по-другому такой преобразователь называют интегратором:

const

:: a -> St b a

integral :: Num a => St a a

• Перепишите с помощью fix несколько стандартных функций для списков. Например map, foldr, foldl,

zip, repeat, cycle, iterate.

Старайтесь найти наиболее краткое выражение, пользуйтесь функциями высшего порядка и частичным

применением. Например рассмотрим функцию repeat:

repeat :: a -> [a]

repeat a = a : repeat a

Запишем с fix:

repeat a = fix $ \xs -> a : xs

Заметим, что мы можем избавиться от аргумента xs с помощью сечения:

repeat a = fix (a:)

Но мы можем пойти ещё дальше, если вспомним, что функция двух аргументов (:) является функцией

от одного аргумента (:) :: a -> ([a] -> [a]), которая возвращает функцию одного аргумента:

repeat = fix . (:)

Смотрите в этом выражении мы составили композицию двух функций. Функция (:) примет первый

аргумент и вернёт функцию, как раз то, что и нужно для fix.

Упражнения | 85

Глава 6

Функторы и монады: теория

Мы научились комбинировать функции наиболее общего типа a -> b. В этой главе мы посмотрим на

специальные функции и способы их комбинирования. Cпециальными функциями мы будем называть такие

функции, результат которых имеет некоторую известную нам структуру. Среди них функции, которые могут

вычислить значение или упасть, или функции, которые возвращают сразу несколько вариантов значений.

Для составления таких функций из простейших в Haskell предусмотрено несколько классов типов. Это функ-

торы и монады. Их мы и рассмотрим в этой главе.

6.1 Композиция функций

Центральной функцией этой главы будет функция композиции. Вспомним её определение для функций

общего типа:

(. ) :: (b -> c) -> (a -> b) -> (a -> c)

f . g = \x -> f (g x)

Композиция двух функций f и g это такая функция, в которой мы сначала применяем g, а затем f. Для того

чтобы тип функции стал более наглядным, мы определим эту функцию немного по-другому. Мы поменяем

аргументы местами.

(>> ) :: (a -> b) -> (b -> c) -> (a -> c)

f >> g = \x -> g (f x)

Мы будем изображать функции кружками, а значения – стрелками (рис. 6.1). Значения словно текут от

узла к узлу по стрелкам. Поскольку тип стрелки выходящей из f совпадает с типом стрелки входящей в g мы

можем соединить их и получить составную функцию (f>> g).

a

f

b

b

g

c

b

a

g

f

c

a

f>>g

c

Рис. 6.1: Композиция функций

86 | Глава 6: Функторы и монады: теория

Класс Category

С помощью операции композиции можно обобщить понятие функции. Для этого существует класс

Category:

class Category cat where

id

:: cat a a

(>> ) :: cat a b -> cat b c -> cat a c

Функция cat это тип с двумя параметрами, в котором выделено специальное значение id, которое остав-

ляет аргумент без изменений. Также мы можем составлять из простых функций сложные с помощью компо-

зиции, если функции совпадают по типу. Здесь мы для наглядности также заменили метод (. ) на (>> ), но

суть остаётся прежней. Для любого экземпляра класса должны выполняться свойства:

f

>> id

== f

id >> f

== f

f >> (g >> h) == (f >> g) >> h

Первые два свойства говорят о том, что id является нейтральным элементом для (>> ) слева и справа.

Третье свойство говорит о том, что нам не важно в каком порядке проводить композицию. Можно проверить,

что эти правила выполнены для функций.

Специальные функции

Все специальные функции, которые мы рассмотрим в этой главе будут иметь один и тот же тип:

a -> m b

Смотрите вместо произвольного типа b функция возвращает m b. Единственное, что будет меняться от

раздела к разделу это тип m. Добавив этот тип к результату, мы сузили область значений функции. Простым

примером таких функций могут быть функции, которые возвращают списки:

a -> [b]

Если раньше наши функции могли возвращать произвольное значение b, то теперь мы знаем, что все

результирующие значения таких функций будут списками.

При этом для каждого такого m мы попытаемся построить свой замкнутый мир специальных функций a

-> m b. Он будет жить внутри вселенной всех произвольных функций типа a -> b. В этом нам поможет

специальный класс типов, который называется категорией Клейсли (эта конструкция носит имя математика

Хенрика Клейсли).

class Kleisli m where

idK

:: a -> m a

(*> ) :: (a -> m b) -> (b -> m c) -> (a -> m c)

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

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

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

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

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

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

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

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

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