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

Мы берём тип Maybe a и оборачиваем его с помощью декларации newtype. Экземпляр класса Monoid в данном случае выглядит следующим образом:

instance Monoid (Firsta) where

   mempty = First Nothing

   First (Just x) `mappend` _ = First (Just x)

   First Nothing `mappend` x = x

Значение mempty – это просто Nothing, обёрнутое с помощью конструктора First. Если первый параметр функции mappend является значением Just, мы игнорируем второй. Если первый параметр – Nothing, тогда мы возвращаем второй параметр в качестве результата независимо от того, является ли он Just или Nothing:

ghci> getFirst $ First (Just 'a') `mappend` First (Just 'b')

Just 'a'

ghci> getFirst $ First Nothing `mappend` First (Just 'b')

Just 'b'

ghci> getFirst $ First (Just 'a') `mappend` First Nothing

Just 'a'

Тип First полезен, когда у нас есть множество значений типа Maybe и мы хотим знать, является ли какое-либо из них значением Just. Для этого годится функция mconcat:

ghci> getFirst . mconcat . map First $ [Nothing, Just 9, Just 10]

Just 9

Если нам нужен моноид на значениях Maybe a – такой, чтобы оставался второй параметр, когда оба параметра функции mappend являются значениями Just, то модуль Data.Monoid предоставляет тип Last a, который работает, как и тип First a, но при объединении с помощью функции mappend и использовании функции mconcat сохраняется последнее значение, не являющееся Nothing:

ghci> getLast . mconcat . map Last $ [Nothing, Just 9, Just 10]

Just 10

ghci> getLast $ Last (Just "один") `mappend` Last (Just "два")

Just "two"

<p>Свёртка на моноидах</p>

Один из интересных способов ввести моноиды в работу заключается в том, чтобы они помогали нам определять свёртки над различными структурами данных. До сих пор мы производили свёртки только над списками, но списки – не единственная структура данных, которую можно свернуть. Мы можем определять свёртки почти над любой структурой данных. Особенно хорошо поддаются свёртке деревья.

Поскольку существует так много структур данных, которые хорошо работают со свёртками, был введён класс типов Foldable. Подобно тому как класс Functor предназначен для сущностей, которые можно отображать, класс Foldable предназначен для вещей, которые могут быть свёрнуты! Его можно найти в модуле Data.Foldable; и, поскольку он экспортирует функции, имена которых конфликтуют с именами функций из модуля Prelude, его лучше импортировать, квалифицируя (и подавать с базиликом!):

import qualified Data.Foldable as F

Чтобы сэкономить драгоценные нажатия клавиш, мы импортировали его, квалифицируя как F.

Так какие из некоторых функций определяет этот класс типов? Среди них есть функции foldr, foldl, foldr1 и foldl1. Ну и?.. Мы уже давно знакомы с ними! Что ж в этом нового? Давайте сравним типы функции foldr из модуля Foldable и одноимённой функции из модуля Prelude, чтобы узнать, чем они отличаются:

ghci> :t foldr

foldr :: (a –> b –> b) –> b –> [a] –> b

ghci> :t F.foldr

F.foldr :: (F.Foldable t) => (a –> b –> b) –> b –> t a –> b

А-а-а! Значит, в то время как функция foldr принимает список и сворачивает его, функция foldr из модуля Data.Foldable принимает любой тип, который можно свернуть, – не только списки! Как и ожидалось, обе функции foldr делают со списками одно и то же:

ghci> foldr (*) 1 [1,2,3]

6

ghci> F.foldr (*) 1 [1,2,3]

6

Другой структурой данных, поддерживающей свёртку, является Maybe, которую мы все знаем и любим!

ghci> F.foldl (+) 2 (Just 9)

11

ghci> F.foldr (||) False (Just True)

True

Но сворачивание значения Maybe не очень-то интересно. Оно действует просто как список с одним элементом, если это значение Just, и как пустой список, если это значение Nothing. Давайте рассмотрим чуть более сложную структуру данных.

Помните древовидную структуру данных из главы 7? Мы определили её так:

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show)

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

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

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

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

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

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

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

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

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