|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[15] Возобновления представляют будущие вычисления, как функцию от промежуточного результата к конечному результату. В выносимом возобновлении стиле вычисления построены из последовательностей вложенных возобновлений, заканчивающихся конечным возобновлением (часто идентификатором), которое создаёт конечный результат. С тех пор как возобновления являются функциями, представляющими будущее вычисления, обработка функций возобновления может достичь сложных обработок будущего вычисления, как, например, прерывание вычисления в середине, прерывание части вычислений, возобновление вычислений и чередование выполнения вычислений. Монада Continuation приспосабливает CPS к структуре монады. 2.10.3. Определение - r - это конечный результирующий тип всего вычисления newtype Cont r a = Cont { runCont :: ((a -> r) -> r) } instance Monad (Cont r) where return a= Cont $ \k -> k a -- return a = \k -> k a (Cont c) >>= f= Cont $ \k -> c (\a -> runCont (f a) k) - c >>= f = \k -> c (\a -> f a k) Монада Continuation представляет вычисления в выносимом возобновления стиле. Cont r a - это CPS вычисление, которое создает промежуточный результат типа а в пределах CPS вычисления, чей конечный результирующий тип - r. Возвращаемая функция просто создаёт возобновление, которое передаёт значение. Оператор >>= добавляет связанную функцию к возобновленной цепочке. class (Monad m) => MonadCont m where callCC :: ((a -> m b) -> m a) -> m a instance MonadCont (Cont r) where callCC f = Cont $ \k -> runCont (f (\a -> Cont $ \ -> k a)) k Класс MonadCont создает функцию callCC, которая создает возобновленный механизм выхода для использования монадами Continuation. Возобновления выхода позволяют вам прервать текущее вычисление и возвратить непосредственно значение. Они достигают похожего результата с throwError и catchError в монаде Error. Функция callCC вызывает функцию с таким текущим возобновлением, как её аргумент (отсюда имя). Стандартная идиома, используемая callCC - это создание -выражений для того, чтобы назвать возобновление. Затем вызов названного возобновления везде в пределах его области будет избавлять от вычисления, даже если находится на много слоёв глубже во вложенных вычислениях.
В добавлении к механизму вывода, предусмотренному callCC, монада Continuation может быть использована для выполнения других, более мощных обработок возобновления. Эти другие механизмы имеют довольно специализированное использование, однако, и злоупотребление ими может легко создать зверски затемнённый код; поэтому они не будут охвачены здесь. 2.10.4. Пример Этот пример показывает фрагмент того, как работает возобновление выхода. Функция в примере использует возобновления выхода для выполнения сложных преобразований над целыми числами. Код, имеющийся в example18.hs - Мы используем монаду Continuation, чтобы выполнить "выходы" из блоков -- кода. Эта функция осуществляет сложную управляющую структуру для обработки -- чисел: -- Ввод (n) Вывод Показательный Список 0-9 n ничего 10-199 число цифр в (n/2) цифры из (n/2) 200-19999 n цифры из (n/2) 20000-1999999 (n/2) назад ничего >= 2000000 сумма цифр из (n/2) цифры из (n/2) определяет "exit1" fun:: Int -> String fun n= ("runCont1 id) $ do str <- callCC $ \exit1 -> do - when (n < 10) (exit1 (show n)) let ns = map digitToInt (show (n "div" 2)) n <- callCC $ \exit2 -> do -- определяет "exit2" when ((length ns) < 3) (exit2 (length ns)) when ((length ns) < 5) (exit2 n) when ((length ns) < 7) $ do let ns = map intToDigit (reverse ns) exit1 (dropWhile (==0) ns) -- освобождает 2 уровня return $ sum ns return $ "(ns = " ++ (show ns) ++ ") " ++ (show n) return $ "Answer: " ++ str
3. МОНАДЫ В РЕАЛЬНОМ МИРЕ 3.1.Introduction Part I has introduced the monad concept and Part II has provided an understanding of a number of common, useful monads in the standard Haskell libraries. This is not enough to put monads into heavy practice, however, because in the real world you often want computations which combine aspects of more than one monad at the same time, such as stateful, non-determistic computations or computations which make use of continuations and perform I/O. When one computation is a strict subset of the other, it is possible to perform the monad computations separately, unless the sub-computation is performed in a one-way monad. Often, the computations cant be performed in isolation. In this case, what is needed is a monad that combines the features of the two monads into a single computation. It is inefficient and poor practice to write a new monad instance with the required characteristics each time a new combination is desired. Instead, we would prefer to develop a way to combine the standard monads to produce the needed hybrids. The technique that lets us do exactly that is called monad transformers. Monad transformers are the topic of Part III, and they are explained by revisiting earlier examples to see how monad transformers can be used to add more realistic capabilities to them. It may be helpful to review the earlier examples as they are re-examined. 3.2.Combining monads the hard way Before we investigate the use of monad transformers, we will see how monads can be combined without using transformers. This is a useful excercise to develop insights into the issues that arise when combining monads and provides a baseline from which the advantages of the transformer approach can be measured. We use the code from example 18 (the Continuation monad) to illustrate these issues, so you may want to review it before continuing. 3.2.1. Nested Monads Some computations have a simple enough structure that the monadic computations can be nested, avoiding the need for a combined monad altogether. In Haskell, all computations occur in the IO monad at the top level, so the monad examples we have seen so far all actually use the technique of nested monadic computations. To do this, the computations perform all of their input at the beginning - usually by reading arguments from the command line - then pass the values on to the monadic computations to produce results, and finally perform their output at the end. This structure avoids the issues of combining monads but makes the examples seem contrived at times.
|
Среды: 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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||