Введение
Монада в функциональном программировании — это структура, объединяющая фрагменты программы (функции) и оборачивающая их возвращаемые значения в тип с дополнительными вычислениями. Помимо определения оборачивающего монодического типа, монады определяют два оператора: один для помещения значения в тип монады, а другой — для композиции функций, возвращающих значения этого типа (такие функции называются монадическими). Языки общего назначения используют монады для уменьшения объема шаблонного кода, необходимого для распространенных операций (например, обработки неопределенных значений или функций, которые могут завершиться с ошибкой, или инкапсуляции служебного кода). Функциональные языки используют монады для преобразования сложных последовательностей функций в лаконичные конвейеры, абстрагирующие управление потоком и побочные эффекты. И само понятие монады, и сам термин изначально пришли из теории категорий, где монада определяется как функтор с дополнительной структурой. Поскольку функции с несколькими свободными переменными часто встречаются в программировании, монады, описанные в этой статье, технически являются тем, что теоретики категорий называют сильными монадами. Так как монады делают семантику вычислений явной, их также можно использовать для реализации удобных возможностей языка. Некоторые языки, такие как Haskell, даже предоставляют встроенные определения общей структуры монады и распространенных экземпляров в своих основных библиотеках.
the concept in category theory
In functional programming, a monad is a structure that combines program fragments (functions) and wraps their return values in a type with additional computation. In addition to defining a wrapping monadic type, monads define two operators: one to wrap a value in the monad type, and another to compose together functions that output values of the monad type (these are known as monadic functions). General purpose languages use monads to reduce boilerplate code needed for common operations (such as dealing with undefined values or fallible functions, or encapsulating bookkeeping code). Functional languages use monads to turn complicated sequences of functions into succinct pipelines that abstract away control flow, and side effects. Both the concept of a monad and the term originally come from category theory, where a monad is defined as a functor with additional structure. efn|Due to the fact that functions on multiple free variables are common in programming, monads as described in this article are technically what category theorists would call strong monads. Since monads make semantics explicit for a kind of computation, they can also be used to implement convenient language features. Some languages, such as Haskell, even offer pre built definitions in their core libraries for the general monad structure and common instances.
История
Термин "монад" в программировании фактически восходит к языкам программирования APL и J, которые тяготеют к чисто функциональному стилю. Однако в этих языках "монад" – это лишь сокращение для функции, принимающей один параметр (функция с двумя параметрами называется "диадой" и так далее). Математик Роджер Годмент первым сформулировал концепцию монады (назвав её "стандартной конструкцией") в конце 1950-х годов, хотя термин "монад", который стал доминирующим, популяризировал теоретик категорий Сондерс Мак-Лейн. Форма, определённая выше с использованием bind, однако, была первоначально описана в 1965 году математиком Генрихом Клейсли, чтобы доказать, что любая монада может быть охарактеризована как сопряжение между двумя (ковариантными) функторами. Начиная с 1980-х годов, в компьютерном сообществе начало возникать смутное представление о монадическом паттерне. По словам исследователя языков программирования Филиппа Уодлера, учёный-компьютерщик Джон К. Рейнольдс предвидел несколько его аспектов в 1970-х и начале 1980-х годов, когда он обсуждал ценность стиля передачи продолжения, теории категорий как богатого источника для формальной семантики и типового различия между значениями и вычислениями. Учёный-компьютерщик Эухенио Могги первым явно связал монаду теории категорий с функциональным программированием в докладе на конференции в 1989 году, за которым последовала более доработанная публикация в журнале в 1991 году. В более ранних работах несколько учёных-компьютерщиков использовали теорию категорий для обеспечения семантики лямбда-исчисления. Ключевым прозрением Могги было то, что реальная программа – это не просто функция от значений к другим значениям, а скорее преобразование, формирующее вычисления над этими значениями. При формализации в терминах теории категорий это приводит к выводу, что монады – это структура для представления этих вычислений. Сообщество Haskell продолжило применять монады ко многим задачам функционального программирования, и в 2010-х годах исследователи, работающие с Haskell, в конечном итоге признали, что монады являются аппликативными функторами; и что как монады, так и стрелки являются моноидами. Поначалу программирование с монадами в основном ограничивалось Haskell и его производными, но поскольку функциональное программирование повлияло на другие парадигмы, многие языки включили в себя монадический паттерн (в духе, если не в названии). Формулировки теперь существуют в Scheme, Perl, Python, Racket, Clojure, Scala, F#, и также рассматриваются для нового стандарта ML.
Анализ
Одним из преимуществ паттерна монады является привнесение математической строгости в композицию вычислений. Законы монады можно использовать не только для проверки корректности реализации, но и возможности, предоставляемые связанными структурами (такими как функторы), могут быть использованы посредством подтипирования.
Продолжение монады
Продолжение monadefn|name= mccan|1= Читателю может быть интересно ознакомиться с работой Макканна. Алгебраически, связь между двумя (некоммутативными) аспектами моноидов напоминает связь в почти полукольце, и некоторые аддитивные монады действительно подпадают под это определение. Однако не все аддитивные монады удовлетворяют законам дистрибутивности даже почти полукольца. Другие применяли их и к более динамичным, операционным задачам, например, для реализации итераторов в языке программирования.