52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 108

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 108

Рис. 6.10: Функция-накопитель

data Writer msg b = Writer (b, msg)

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

runWriter (Writer a) = a

Тип функции примет вид:

a -> Writer msg b

Значения типа msg мы будем называть сообщениями. Смысл функций a -> Writer msg b заключается

в том, что при вычислении они накапливают в значении msg какую-нибудь информацию. Это могут быть

отладочные сообщения. Или база данных, которая открыта для всех функций на запись.

Класс Monoid

Как мы будем накапливать результат? Пока мы умеем лишь возвращать из функции пару значений. Одно

из них нам нужно передать в следующую функцию, а что делать с другим?

На помощь нам придёт класс Monoid, он определён в модуле Data.Monoid:

class Monoid a where

mempty

:: a

mappend :: a -> a -> a

В этом классе определено пустое значение mempty и бинарная функция соединения двух значений в одно.

Этот класс очень похож на класс Category и Kleisli. Там тоже было значение, которое ничего не делает и

операция составления нового значения из двух простейших значений. Даже свойства класса похожи:

mempty

‘mappend‘ f

= f

f

‘mappend‘ mempty

= f

f ‘mappend‘ (g ‘mappend‘ h) =

(f ‘mappend‘ g) ‘mappend‘ h

a

g

f

b

b

c

msg

msg

b

a

g

f

c

MsgG

++

MsgF ++ MsgG

MsgF

a

f*>g

c

msg

Рис. 6.11: Композиция функций-накопителей