Неформальные описания обозначаются так. Вообще примеры монад лучше всего ботаются по файлу code/monads/Expr4.ml из репы Какаду (есть в коммах), потому что там есть код конкретных примеров. Но если вера в свои силы минимальна, я постарался описать основные особенности + применения каждой монады.

‡ Определение монады

Untitled

Вообще понятие монады происходит из математики, а именно из теории категорий. Но мы, естественно, рассматриваем это понятие только с точки зрения программирования.

Монады используются для моделирования вычислений. Думайте о вычислении как о функции, которая не только сопоставляет аргумент с результатом функции, но также выполняет “нечто большее”. Нечто большее - это эффект, который функция оказывает в результате вычисления. Например, эффект может включать ошибку интерпретации (Option и Result монады, про них дальше). В билете как раз рассмотрены различные эффекты, которые можно моделировать с помощью монад. Монады обеспечивают абстракцию эффектов и помогают убедиться, что эффекты выполняются в контролируемом порядке. Например, что все записи в лог сделаны в нужном порядке.

<aside> 💡 Монада — параметрический тип данных, у которого есть функции return и bind, которые подчиняются трем законам.

</aside>

Ниже сигнатура функций return и bind:

module type MONAD = sig
  type 'a t

  val return : 'a -> 'a t
  val bind : 'a t -> ('a -> 'b t) -> 'b t
end

Можно относиться к монаде как к некоторому контексту. Чтобы понять, что делают эти функции в общем случае, лучше всего посмотреть на их сигнатуры.

‡ Return

return принимает некоторое значение типа 'a и “запаковывает” его в контекст.

В терминах вычислений, return предназначен для того, чтобы иметь какой-то тривиальный эффект. Например, если монада представляет вычисления, побочным эффектом которых является добавление в лог (writer монада), то тривиальным эффектом было бы ничего не добавлять.

‡ Bind

bind принимает на вход:

bind применяет свой второй аргумент к первому. Для этого требуется извлечь значение 'a из контекста (т. е. распаковать), применить к нему функцию и вернуть результат.

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

Обычное обозначение для bind - это инфиксный оператор, записываемый >>= и произносимый как “bind”. И еще раз напоминалка (теперь вместо bind в коде пишем >>=):