Монады и многое другое в программировании на Haskell

Что такое монада? Что такое программирование? Какое отношение они имеют друг к другу?

Чтобы процитировать Википедию, монада это:

Монада — это алгебраическая структура в теории категорий, а в Haskell она используется для описания вычислений как последовательности шагов и для обработки побочных эффектов, таких как состояние и ввод-вывод. Монады абстрактны, и у них есть много полезных конкретных экземпляров. Монады обеспечивают способ структурирования программы.

Монады — это, прежде всего, решения для решения повторяющихся проблем с кодом, независимо от того, что вы пишете. В этом смысле концепция монад похожа на то, что инженеры-программисты называют «сквозными задачами». Список решает частую проблему: вам требуется простая коллекция элементов одного типа с определенным простым поведением и свойствами производительности. Кроме того, есть тип Maybe, который избавляет вас от необходимости писать множество проверок нулевого указателя или от необходимости отлаживать код, которого недостаточно. А ввод-вывод — это то, что в первую очередь позволяет вам взаимодействовать с программой.

Монады помогают в стратегиях компонуемости. Монада — это метастратегия смешивания вычислений с более сложными. Считайте монады дисциплинированной техникой для создания «конвейеров» в вашем приложении. Конвейеры — это средство для получения мощности, но они не всегда проверяются на тип (особенно в языках оболочки). Программы, которые принимают ввод и выдают вывод по всему конвейеру, несут ответственность за то, чтобы их входы и выходы имели правильный формат — другими словами, что входы и выходы имеют правильные (неявные) «типы». Статическая типизация в Haskell избавляет вас от этой работы по кодированию, а также от проблем «мусор на входе/выходе», которые возникают, когда код проверки формата не соответствует требованиям.

Зачем использовать монады, каково их использование

Монады являются важной частью системы ввода-вывода Haskell. Понимание монад не требуется для ввода-вывода в Haskell, но оно поможет вам писать лучший код и расширить свои возможности.

  • Монады — важные инструменты для структурирования функциональных программ для программистов. Они обладают тремя уникальными характеристиками, которые делают их особенно полезными:
  • Модульность. Они позволяют собирать вычисления из более мелких вычислений, сохраняя технику комбинирования отдельно от реальных вычислений.
  • Гибкость. Функциональные программы, разработанные с использованием монад, значительно более гибкие, чем аналогичные программы, написанные без них. Это связано со способностью монады концентрировать вычислительный подход в одном месте, а не требовать, чтобы он был разбросан по всей программе.
  • Изоляция. Их можно использовать для создания вычислительных структур императивного стиля, которые надежно отделены от основной части функциональной программы. Это полезно для добавления побочных эффектов (например, ввода-вывода) и состояния (которое нарушает ссылочную прозрачность) в чистый функциональный язык, такой как Haskell.

Полиморфные типы похожи на контейнеры, которые могут содержать значения различных типов. Таким образом, Maybe Int можно рассматривать как контейнер Maybe, который содержит значение Int (или Nothing), в то время как Maybe String — это контейнер Maybe, который содержит значение String (или ничего). Мы также можем сделать тип контейнера полиморфным в Haskell, чтобы мы могли писать «ma» для представления контейнера любого типа, содержащего значение любого типа!

Возможно Монада

Монада в Haskell состоит из конструктора типа (называемого m), функции, которая создает значения этого типа (a -> m a), и функции, которая комбинирует значения этого типа с вычислениями, которые производят значения этого типа для получения новое вычисление для значений этого типа (ma -> (a -> m b) -> m b). Хотя контейнер остается прежним, содержимое внутри контейнера может варьироваться. Обычно при обсуждении монад конструктор монадного типа обычно называют «m». Функция, которая создает значения этого типа, называется «return», а третья функция известна как «bind», но пишется «››=».

-- the type of monad m
data m a = ...

-- return takes a value and embeds it in the monad.
return :: a -> m a

-- bind is a function that combines a monad instance m a with a computation
-- that produces another monad instance m b from a's to produce a new
-- monad instance m b
(>>=) :: m a -> (a -> m b) -> m b

Конструктор типа монады, грубо говоря, определяет тип вычисления, функция возврата предоставляет примитивные значения этого типа вычисления и ››= объединяет вычисления этого типа для создания более сложных вычислений этого типа. Конструктор типа m по аналогии с контейнером — это контейнер, в котором могут храниться различные значения. m — это контейнер, который содержит тип значения. Значение помещается в контейнер монад через функцию возврата. Функция ››= берет значение из контейнера монады и передает его функции, которая возвращает контейнер монады с новым значением другого типа. Поскольку она привязывает значение контейнера монады к первому аргументу функции, функция ››= известна как «bind».

Список — это монада

Мы видели, что конструктор типа Maybea представляет собой монаду для построения вычислений, которые могут не вернуть значение. Вы можете быть удивлены, узнав, что другой распространенный конструктор типа Haskell, [] (для построения списков), также является монадой. Монада List позволяет нам создавать вычисления, которые могут возвращать 0, 1 или более значений.

Представление неоднозначных вычислений, то есть вычислений с нулем, одним или несколькими возможными результатами, — это одно из применений функций, возвращающих списки. Неоднозначность может усугубляться в вычислении, состоящем из неоднозначных подвычислений, или может в конечном итоге разрешиться в один разрешенный результат или вообще в отсутствие разрешенного результата. Набор альтернативных вычислительных состояний представлен в виде списка во время этой процедуры. В результате монада List воплощает технику выполнения одновременных вычислений по всем возможным путям неоднозначной операции.

Монада — это метастратегия смешивания вычислений с более сложными. Считайте, что монады — это метод дисциплины типов для создания «конвейеров» в вашем приложении. Конвейеры — это средство для получения мощности, но они не всегда проверяются на тип (особенно в языках оболочки). Программы, которые принимают ввод и выдают вывод по всему конвейеру, несут ответственность за обеспечение того, чтобы их входы и выходы имели правильный формат — в Другими словами, входы и выходы имеют правильные (неявные) «типы». Статическая типизация в Haskell избавляет вас от этой работы по кодированию, а также от проблем «мусор на входе/выходе», которые возникают, когда код проверки формата не соответствует требованиям.