Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[13]

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

Код, используемый в example16.hs

- Это абстрактное синтаксическое представление шаблона -- Текст Переменная Назначение Включение Состав

data Template

data Definition

T String V Template Q Template

I Template [Definition]

C [Template]

D Template Template

-- Наша среда состоит из ассоциативного списка именованных шаблонов и -- ассоциативного списка поименованных переменных величин data Environment = Env {templates::[(String,Template)],

variables::[(String,String)]}

-- поиск переменной в среды lookupVar

lookupVar name env

-- поиск шаблона в среде lookupTemplate lookupTemplate name env

String -> Environment -> Maybe String lookup name (variables env)

String -> Environment -> Maybe Template lookup name (templates env)

-- добавляет список разрешенных определений к среде

addDefs:: [(String,String)] -> Environment -> Environment

addDefs defs env= env {variables = defs ++ (variables env)}

-- решает определения и создает пару ( имя, величина) resolveDef:: Definition -> Reader Environment

resolveDef (D t d)= do name <- resolve t

value <- resolve d return (name, value)

(String,String)

-- переводит шаблон встроку resolve:

resolve (T s)=

resolve (V t)=

resolve (Q t)

resolve (I t ds)=

tmplName <- resolve t

body <- asks (lookupTemplate tmplName)

Template -> Reader Environment (String) return s

do varName <- resolve t

varValue <- asks (lookupVar varName) return $ maybe "" id varValue do tmplName <- resolve t

body <- asks (lookupTemplate tmplName) return $ maybe "" show body

ФП 02005-03 01

№ докум.

Копипова Фопмат


case body of

Just t -> do

defs <- mapM resolveDef ds local (addDefs defs) (resolve t) Nothing -> return "" resolve (C ts) = (liftM concat) (mapM resolve ts)

Чтобы использовать монаду Reader для перевода шаблона t в строку, вам просто нужно выполнить runReader (resolve t) env.

2.9. Монада Writer

2.9.1. Обзор

Таблица 9. Свойства монады Writer

Тип вычисления:

Вычисления, которые создают поток данных в дополнении к вычисленным величинам.

Стратегия связывания:

Величина монады Writer- пара (вычислительная величина, регистрационная величина). Связь заменяет вычислительную величину результатом применения связанной функции к предшествующей величине и добавляет любые регистрационные данные от вычисления до существующих регистрационных данных.

Полезна для:

Регистрация, или другие вычисления, которые производят выход «на стороне».

Нуль и плюс:

Пример:

Writer [String] a

2.9.2.Мотивация

Желательно использовать для вычисления генерации выхода «на стороне». Регистрация и слежение - наиболее общие примеры, в которых данные сгенерированы в процессе вычисления, которое мы хотим сохранить, но это не первичный результат вычисления.

Явное управление регистрацией или отслеживанием данных может загромоздить код и вызвать тонкие дефекты, как, например, пропущенные регистрационные данные. Монада Writer обеспечивает чистый путь для управления выходом, не загромождая основное вычисление.

2.9.3.Определение

Показанное здесь определение использует классы многопараметрического типа и junDeps, которые не являются стандартными в Haskell 98. Нет необходимости полностью понимать эти детали, чтобы использовать монаду Writer.

ФП 02005-03 01

Лист 46

№ докум.

Копиоова Фоомат


Для того, чтобы полностью понимать это определение, вам нужно знать о классе Monoid в языке Haskell, который представляет собой математическую структуру, представляющую моноид так же, как и класс Monad представляет структуру монады.

Хорошей новостью является то, что моноиды проще, чем монады. Моноид - это множество объектов, единственный элемент тождества и ассоциативный бинарный оператор над множеством объектов. Моноид должен подчиняться некоторым математическим законам, таким, при которых приложение оператора к любым величинам из установленных даёт другую величину при установке, и всякий раз, когда один операнд оператора является элементом тождества, результат равняется другому операнду. Вы можете обратить внимание, что эти законы являются такими же, как и законы, управляющие mzero и mplus для примеров MonadPlus. Это происходит потому, что монады с нулём и плюсом являются монадами, которые также являются моноидами!

Одним из примеров математических моноидов являются натуральные числа с элементом тождества 0 и двоичный оператор для сложения, а также натуральные числа с элементом тождества 1 и двоичный оператор для умножения.

В языке Haskell моноид состоит из типа, элемента тождества и двоичного оператора. Язык Haskell определяет класс Monoid (в Data.Monoid), чтобы обеспечивать стандартную конвенцию для работы с моноидами: элемент тождества назван mempty, а оператор назван mappend. Наиболее общий использованный стандартный моноид в языке Haskell - это список, но функции типа (а -> a) также формируют моноид.

Вы должны быть внимательными при использовании списка как моноиды для Writer, так как там может быть штраф при исполнении, связанный с операцией mappend, так как выход увеличивается. В этом случае структура данных, которая поддерживает быстрые операции добавления, должна быть более подходящим выбором.

newtype Writer w a= Writer { runWriter :: (a,w) }

instance (Monoid w) => Monad (Writer w) where

return a= Writer (a,mempty)

(Writer (a,w)) >>= f = let (a, w) = runWriter $ f a

in Writer (a,w mappend w)

Монада Writer поддерживает пару (величина, протокол), где регистрационный тип должен быть моноидом. Возвращаемая функция просто возвращает величину вместе с пустым протоколом. Связь выполняет связанную функцию, использующую текущую величину как ввод, и добавляет любой регистрационный выход в существующий протокол.

class (Monoid w, Monad m) => MonadWriter w m m -> w where pass:: m (a,w -> w) -> m a

listen :: m a -> m (a,w)

tell:: w -> m ()

ФП 02005-03 01

Лист 47

№ докум.

Копипова Фопмат



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25]