|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[17] £ то св а: =з A transformer version of the Reader monad, called ReaderT, exists which adds a monad type constructor as an addition parameter. ReaderTr m a is the type of values of the combined monad in which Reader is the base monad and m is the inner monad. ReaderTr m is an instance of the monad class, and the runReaderT::(r -> m a) function performs a computation in the combined monad and returns a result of type m a. Using the transformer versions of the monads, we can produce combined monads very simply. ReaderTr IO is a combined Reader+IO monad. We can also generate the non-transformer version of a monad from the transformer version by applying it to the Identity monad. So ReaderTr Identity is the same monad as Reader r. If your code produces kind errors during compilation, it means that you are not using the type cosntructors properly. Make sure that you have supplied the correct number of parameters to the type constructors and that you have not left out any parenthesis in complex type expressions. 3.3.2. Lifting When using combined monads created by the monad transformers, we avoid having to explicitly manage the inner monad types, resulting in clearer, simpler code. Instead of creating additional do-blocks within the computation to manipulate values in the inner monad type, we can use lifting operations to bring functions from the inner monad into the combined monad. Recall the liftM family of functions which are used to lift non-monadic functions into a monad. Each monad transformer provides a lift function that is used to lift a monadic computation into a combined monad. Many transformers also provide a liftIO function, which is a version of lift that is optimized for lifting computations in the IO monad. To see this in action, we will continue to develop our previous example in the Continuation monad. Code available in example21.hs fun :: IO String fun = ("runContT1 return) $ do n <- liftIO (readLn::IO Int) str <- callCC $ \exit1 -> do- define "exit1" when (n < 10) (exit1 (show n)) let ns = map digitToInt (show (n "div1 2)) n <- callCC $ \exit2 -> do - define "exit2" when ((length ns) < 3) (exit2 (length ns)) when ((length ns) < 5) $ do liftIO $ putStrLn "Enter a number:" x <- liftIO (readLn::IO Int) exit2 x when ((length ns) < 7) $ do let ns = map intToDigit (reverse ns) exitl (dropWhile (==0) ns) - escape 2 levels
return $ "(ns = return $ "Answer: ++ (show ns) ++ ") ++ str ++ (show n) Compare this function using ContT, the transformer version of Cont, with the original version to see how unobtrusive the changes become when using the monad transformer. Nested monads from example 19 fun = do n <- (readLn::IO Int) return $ ("runCont" id) $ do str <- callCC $ \exitl -> do when (n < l0) (exitl (show n)) let ns = map digitToInt (show (n "div" 2)) n <- callCC $ \exit2 -> do when ((length ns) < 3) (exit2 (length ns)) when ((length ns) < 5) (exit2 n) when ((length ns) < 7) $ do let ns = map intToDigit (reverse ns) exitl (dropWhile (==0) ns) return $ sum ns return $ "(ns = " ++ (show ns) ++ ") " ++ (show n) return $ "Answer: " ++ str Monads combined with a transformer from example 21 fun = ("runContT" return) $ do n <- liftIO (readLn::IO Int) str <- callCC $ \exitl -> do when (n < l0) (exitl (show n)) let ns = map digitToInt (show (n "div" 2)) n <- callCC $ \exit2 -> do when ((length ns) < 3) (exit2 (length ns)) when ((length ns) < 5) $ do liftIO $ putStrLn "Enter a number:" x <- liftIO (readLn::IO Int) exit2 x when ((length ns) < 7) $ do let ns = map intToDigit (reverse ns) exitl (dropWhile (==0) ns) return $ sum ns return $ "(ns = " ++ (show ns) ++ ") " ++ (show n) return $ "Answer: " ++ str The impact of adding the I/O in the middle of the computation is narrowly confined when using the monad transformer. Contrast this with the changes required to achieve the same result using a manually combined monad.
3.4. Standard monad transformers Haskells base libraries provide support for monad transformers in the form of classes which represent monad transformers and special transformer versions of standard monads. 3.4.1.The MonadTrans and MonadIO classes The MonadTrans class is defined in Control.Monad.Trans and provides the single function lift. The lift function lifts a monadic computation in the inner monad into the combined monad. class MonadTrans t where lift :: (Monad m) => m a -> t m a Monads which provide optimized support for lifting IO operations are defined as members of the MonadIO class, which defines the liftIO function. class (Monad m) => MonadIO m where liftIO :: IO a -> m a 3.4.2.Transformer versions of standard monads The standard monads of the monad template library all have transformer versions which are defined consistently with their non-transformer versions. However, it is not the case the all monad transformers apply the same transformation. We have seen that the ContT transformer turns continuations of the form (a->r)->r into continuations of the form (a->m r)->m r. The StateT transformer is different. It turns state transformer functions of the form s->(a,s) into state transformer functions of the form s->m (a,s). In general, there is no magic formula to create a transformer version of a monad - the form of each transformer depends on what makes sense in the context of its non-transformer type.
Original Type Combined Type Either e a s -> (a,s) r -> a
(a -> r) -> r (a -> m r) -> m
|
Среды: 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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||