|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[4] Монада IO - один из примеров монад без обратной связи в языке Haskell. Так как вы не можете выйти из монады IO, невозможно написать функцию, выполняющую вычисление внутри монады IO и при этом не имеющей в своём результате конструктора типов IO. Это значит, что любая функция, результирующий тип которой не содержит конструктор типов IO, гарантированно не использует монаду IO. Другие монады, такие как List и Maybe, возвращают значения. Поэтому возможно написание функций, которые используют эти монады, но при этом возвращают не монадические значения. Удивительная черта монад без обратной связи состоит в том, что они могут поддерживать побочные эффекты в своих монадических операциях, предотвращая при этом разрушение функциональных свойств немонадических частей программы. Рассмотрим простой пример чтения символа, введенного пользователем. Нельзя написать функцию readChar :: Char, потому что она должна каждый раз при вызове возвращать различный символ, в зависимости от того, что ввёл пользователь. Так как Haskell является чистым функциональным языком, то все функции в нём каждый раз при вызове с одними и теми же аргументами должны возвращать одно и то же значение. Зато можно написать функцию ввода/вывода getChar:: IO Char в монаде IO, потому что она может быть использована лишь в последовательности внутри монады без обратной связи. Нет возможности избавиться от конструктора типов IO в сигнатуре какой-либо функции, использующей его, поэтому конструктор типов IO работает как своего рода тег, определяющий функции, которые выполняют операции ввода/вывода. Более того, такие функции полезны лишь внутри монады IO. Таким образом, монада без обратной связи создаёт изолированный вычислительный процесс, функционального языка могут не соблюдаться. котором правила чистого монад - это представление при необходимости получения Другой стандартный приём при определении монадических значений в качестве функций. Тогда значения монадического вычисления «выполняется» результирующая монада и выдаёт результат. 1.4.4. Нулевой элемент и операция «+» Кроме трёх основных законов, описанных выше, некоторые монады подчиняются дополнительным правилам. У монад есть специальное значение mzero и оператор mplus, который подчиняется четырём дополнительным законам: 1)mzero >>= f == mzero 2)m >>= (\x -> mzero) == mzero 3)mzero mplus m == m 4)m mplus mzero == m
Легко запомнить законы для mzero и mplus, если сопоставить mzero с 0, mplus с +, и >> = с * в обычной математике. Монады, включающие в себя нулевой элемент и операцию «+», можно объявить экземплярами класса MonadPlus в языке Haskell: class (Monad m) => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a Продолжая использовать монаду Maybe в качестве примера, можно сказать, что она является экземпляром класса MonadPlus: instance MonadPlus Maybe where mzero = Nothing Nothing "mplus" x = x x "mplus" = x В данном примере Nothing определяется как нулевое значение, а объединение двух значений Maybe даёт в результате то из этих значений, которое не является Nothing. Если оба входных значения равны Nothing, тогда результатом mplus является также Nothing. В монаде списка также есть нулевой элемент и операция «+». Нулевым элементом mzero является пустой список, оператором mplus - оператор конкатенации списков ++. Оператор mplus используется для комбинирования монадических значений из различных вычислений в единственное монадическое значение. В контексте нашего примера клонирования овец можно использовать оператор mplus монады Maybe для определения функции, parent s = (mother s) mplus father s), которая вернёт родителя, если такой есть, или значение Nothing, если у овцы вообще нет родителей. Для овцы с двумя родителями функция mplus вернёт одного из них, в зависимости от точного определения mplus в монаде Maybe. 1.4.5. Резюме Экземпляры класса Monad должны подчиняться так называемым законам монад, которые описывают алгебраические свойства монад. Три основных закона определяют, что функция return эквивалентна справа и слева, и связывающий оператор ассоциативен. Невыполнение этих требований приведет к тому, что монады будут неправильно функционировать, и может вызвать неявные проблемы при использовании нотации do. Помимо функций return и >>=, класс Monad определяет другую функцию, fail. Включение функции fail в монаду не является обязательным, но она удобна в использовании и включена в класс Monad, потому что используется нотацией do языка Haskell.
Некоторые монады кроме основных трёх законов подчиняются ещё и дополнительным правилам. Одним из важнейших классов таких монад являются монады с нулевым элементом (mzero) и операцией «+» (mplus). Для монад, в которых есть элемент mzero и оператор mplus, используется класс MonadPlus. 1.4.6. Упражнения Этот раздел содержит несколько простых упражнений для шлифования навыков читателя по созданию монад, а также для укрепления понимания понятия функции и использования монад списка и Maybe перед более глубоким изучением монадического программирования. Упражнения построены на предыдущем примере клонирования овец, с которым читатель уже должен быть знаком. Упражнение 1: Нотация do Перепишите функции maternalGrandfather, fathersMaternalGrandmother, и mothersPaternalGrandfather из примера 2, используя монадические операторы return и >>=, без помощи нотации do. Упражнение 2: комбинирование монадических значений Напишите функции parent и grandparent с сигнатурой Sheep -> Maybe Sheep. Они должны возвращать одну овцу, отобранную от остальных в соответствии с описанием, или значение Nothing, если такой овцы нет. Подсказка: в данном случае удобно воспользоваться оператором mplus. Упражнение 3: использование монады списка Напишите функции parent и grandparent с сигнатурой Sheep -> [Sheep]. Они должны возвращать всех овец, соответствующих описанию, или пустой список, если таких овец нет. Подсказка: в данном случае удобно использовать оператор mplus из монады списка. Также можно воспользоваться функцией maybeToList, определенной в модуле Maybe, для конвертации значения из типа Maybe в список. Упражнение 4: Использование ограничения класса Monad Монады обеспечивают модульность и многократное использование кода, инкапсулируя вычислительные алгоритмы в модули, которые могут использоваться для формирования множества различных вычислений. Монады также способствуют модульности, позволяя вам изменять монаду, в которой происходит вычисление, для получения различных вариантов вычислений. Это достигается написанием полиморфных функций в конструкторе типов монады, используя (Monad m) =>, (MonadPlus 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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||