|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[14] instance (Monoid w) => MonadWriter(Writer w) where pass (Writer ((a, f), w)) = Writer (a, f w) listen (Writer (a, w)) = Writer ((a, w), w) tell s= Writer ((), s) listens listens f m censor censor f m (MonadWriter w m) => (w -> w) -> m a -> m (a, w) do (a, w) <- m; return (a, f w) (MonadWriter w m) => (w -> w) -> m a -> m a pass $ do a <- m; return (a, f) Класс MonadWriter выделяет множество удобных функций для работы с монадами Writer. Самый простой и наиболее полезный способ - сообщение, которое добавляет одно или более данных к протоколу. Прослушивающая функция переделывает Writer, которая возвращает величину a и создает выход w в Writer, которая создает величину (a, w) и все еще создает выход w. Это допускает вычисление, чтобы «слушать» протокол на выходе, сгенерированный Writer. Передаваемая функция немного усложнена. Она преобразовывает Writer, которая производит величину (a, j) и выход w в Writer, которая производит величину a и выход j w. Это отчасти громоздко, поэтому нормально использован функциональный цензор помощника. Функция цензора берет функцию и Writer и производит новую Writer, чей выход - тот же, но чей регистрационный вход был модифицирован функцией. Прослушивающая функция кроме того управляет тем, что регистрационная часть величины модифицируется поставленной функцией. 2.9.4. Пример В этом примере, мы представляем себе то же простое применение, которое фильтрует пакеты, основываясь на базе правил, сочетающих в себе исходные и предопределённые множества и полезность пакетов. Первичной работой является фильтрование пакетов, но нам должно это нравиться, чтобы создать протокол деятельности. Код, имеющийся в example17.hs - это - формат нашего входного протокола data Entry = Log {count::Int, msg::String} deriving Eq -- добавляем сообщение к протоколу logMsg:: String -> Writer [Entry] () logMsg s= tell [Log 1 s] -- управление одним пакетом filterOne:: [Rule] -> Packet -> Writer [Entry] (Maybe Packet)
++ (show packet)) filterOne rules packet = do rule <- return (match rules packet) case rule of Nothing -> do logMsg ("DROPPING UNMATCHED PACKET: return Nothing (Just r) -> do when(logIt r) (logMsg ("MATCH: " ++ (show r) ++ " <=> " ++ (show packet))) case r of (Rule Accept ) -> return (Just packet) (Rule Reject ) -> return Nothing Это было довольно просто, но что если мы хотим объединить двойные последовательные регистрационные данные? Ни одна из существующих функций не позволяет нам модифицировать выход с предшествующих этапов вычисления, но мы можем использовать хитрость «задержанная регистрация», чтобы добавлять регистрационный вход только после того, как мы получим новый вход, который не соответствует ни одному до него. Код, имеющийся в example17.hs - слияние идентичных данных в конце протокола. Эта функция использует -- [Entry] как тип протокола и тип результата. Когда два идентичных сообщения -- объеденены, результатом является сообщением с увеличенным счётчиком. Когда -- два других сообщения объединены, сначала регистрируется первое сообщение, -- а второе возвращается как результат. [Entry] -> Writer [Entry] [Entry] mergeEntries mergeEntries [] x mergeEntries x [] mergeEntries [el] :: [Entry] -> = return x = return x [e2] = let (Log n msg) = el (Log n msg) = e2 if msg == msg then return [(Log (n+n) msg)] else do tell [el] return [e2] -- Эта с виду сложная функция на самом деле красива и проста. -- Она отображает функцию над списком величин, чтобы получать список Writer, -- тогда выполняется каждый автор и объединяются результаты. Результат -- функции - автор, чья величина является списком всех величин из авторов -- и чей регистрационный выход является результатом свертки оператора слияния -- в личные регистрационные данные ( использование инициала как начального -- протокола величины). groupSame:: (Monoid a) => a ->
(a -> a -> Writer a a) -> [b] -> (b -> Writer a c) -> Writer a [c] groupSame initial merge [] = do tell initial return [] groupSame initial merge (x:xs) fn= do (result,output) <- return (runWriter (fn x)) new <- merge initial output rest <- groupSame new merge xs fn return (result:rest) - эти фильтры - список пакетов, производящих отфильтрованный список пакета и -- протокол деятельности, в котором объединяются последовательные сообщения filterAll :: [Rule] -> [Packet] -> Writer [Entry] [Packet] filterAll rules packets= do tell [Log 1 "STARTING PACKET FILTER"] out <- groupSame [] mergeEntries packets (filterOne rules) tell [Log 1 "STOPPING PACKET FILTER"] return (catMaybes out) 2.10. Монада Continuation
2.10.2. Мотивация Злоупотребление монадой Continuation может привести к созданию кода, который будет невозможно понять и поддержать. Прежде чем использовать монаду Continuation, будьте уверены, что у вас есть твёрдое понимание выносимого возобновления стиля (CPS), и что возобновления представляют собой лучшее решение вашей определённой задачи. Многие алгоритмы, которые требуют возобновлений в других языках, не требуют их в языке Haskell, благодаря ленивой семантике языка Haskell.
|
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||