Читаем Изучай Haskell во имя добра! полностью

ghci> 3 * (2 * (8 * 5))

240

ghci> "ой" ++ ("лю" ++ "ли")

"ойлюли"

ghci> ("ой" ++ "лю") ++ "ли"

"ойлюли"

Мы называем это свойство ассоциативностью. Оператор * ассоциативен, оператор ++ тоже. Однако оператор , например, не ассоциативен, поскольку выражения (5 – 3) – 4 и 5 – (3 – 4) возвращают различные результаты.

Зная об этих свойствах, мы наконец-то наткнулись на моноиды!

<p>Класс типов Monoid</p>

Моноид состоит из ассоциативной бинарной функции и значения, которое действует как единица (единичное или нейтральное значение) по отношению к этой функции. Когда что-то действует как единица по отношению к функции, это означает, что при вызове с данной функцией и каким-то другим значением результат всегда равен этому другому значению. Значение 1 является единицей по отношению к оператору *, а значение [] является единицей по отношению к оператору ++. В мире языка Haskell есть множество других моноидов, поэтому существует целый класс типов Monoid. Он предназначен для типов, которые могут действовать как моноиды. Давайте посмотрим, как определён этот класс типов:

class Monoid m where

   mempty :: m

   mappend :: m –> m –> m mconcat :: [m] –> m

   mconcat = foldr mappend mempty

Класс типов Monoid определён в модуле Data.Monoid. Давайте потратим некоторое время, чтобы как следует с ним познакомиться.

Прежде всего, нам видно, что экземпляры класса Monoid могут быть определены только для конкретных типов, потому что идентификатор m в определении класса типов не принимает никаких параметров типа. В этом состоит отличие от классов Functor и Applicative, которые требуют, чтобы их экземплярами были конструкторы типа, принимающие один параметр.

Первой функцией является mempty. На самом деле это не функция, поскольку она не принимает параметров. Это полиморфная константа вроде minBound из класса Bounded. Значение mempty представляет единицу для конкретного моноида.

Далее, у нас есть функция mappend, которая, как вы уже, наверное, догадались, является бинарной. Она принимает два значения одного типа и возвращает ещё одно значение того же самого типа. Решение назвать так функцию mappend было отчасти неудачным, поскольку это подразумевает, что мы в некотором роде присоединяем два значения. Тогда как оператор ++ действительно принимает два списка и присоединяет один в конец другого, оператор * на самом деле не делает какого-либо присоединения – два числа просто перемножаются. Когда вы встретите другие экземпляры класса Monoid, вы поймёте, что большинство из них тоже не присоединяют значения. Поэтому избегайте мыслить в терминах присоединения; просто рассматривайте mappend как бинарную функцию, которая принимает два моноидных значения и возвращает третье.

Последней функцией в определении этого класса типов является mconcat. Она принимает список моноидных значений и сокращает их до одного значения, применяя функцию mappend между элементами списка. Она имеет реализацию по умолчанию, которая просто принимает значение mempty в качестве начального и сворачивает список справа с помощью функции mappend. Поскольку реализация по умолчанию хорошо подходит для большинства экземпляров, мы не будем сильно переживать по поводу функции mconcat. Когда для какого-либо типа определяют экземпляр класса Monoid, достаточно реализовать всего лишь методы mempty и mappend. Хотя для некоторых экземпляров функцию mconcat можно реализовать более эффективно, в большинстве случаев реализация по умолчанию подходит идеально.

<p>Законы моноидов</p>

Прежде чем перейти к более конкретным экземплярам класса Monoid, давайте кратко рассмотрим законы моноидов.

Вы узнали, что должно иметься значение, которое действует как тождество по отношению к бинарной функции, и что бинарная функция должна быть ассоциативна. Можно создать экземпляры класса Monoid, которые не следуют этим правилам, но такие экземпляры никому не нужны, поскольку, когда мы используем класс типов Monoid, мы полагаемся на то, что его экземпляры ведут себя как моноиды. Иначе какой в этом смысл? Именно поэтому при создании экземпляров класса Monoid мы должны убедиться, что они следуют нижеприведённым законам:

• mempty `mappend` x = x

• x `mappend` mempty = x

• (x `mappend` y) `mappend` z = x `mappend` (y `mappend` z)

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

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

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

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

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

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

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

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

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