Недавно я стер свои знания о том, как работают монады. Я также был введен в понятие «комонадой» , которая описывается как обратный двойной монады . Тем не менее, я не могу обернуть голову вокруг этого.
Чтобы понять монады, я сделал для себя аналогию:
Монады можно рассматривать как «план построения конвейерных выражений».
Чтобы определить новую Monad (новый тип конвейерно-ленточной системы), вам необходимо определить:
- Способ размещения чего-либо на конвейерной ленте, например, «запуск» конвейерной ленты. (Известный как
unitилиreturn)- Способ соединения машины (выражения), которая будет частью конвейерной ленты, с конвейерной лентой. (Известный как
joinилиbindили>>=).(Существует третья операция, которая забирает текущую конвейерную ленту, выбрасывает ее содержимое и запускает новую конвейерную ленту, известную как
>>, но она используется очень редко.)Для правильной совместной работы машин и конвейеров вам необходимо убедиться, что:
- Если вы положили что-то на ленточный конвейер и пропустили его через машину, выходной сигнал должен быть таким же, как при ручной передаче через машину. (Левая идентичность)
- Если вы хотите поместить конвейерную ленту между уже существующей конвейерной лентой, вы не должны иметь конвейерную ленту с конвейерной лентой сверху, а одну длинную конвейерную ленту. (Правильная идентичность)
- Для вывода не должно иметь значения, если вы вручную используете машину A, а затем пропускаете результат через BC, подключенный к конвейеру, или если вы используете AB, подключенную к конвейеру, а затем пропускаете результат вручную через C. Другими словами: ((a >> = b) >> = c) должен совпадать с (a >> = (b >> = c)) (ассоциативность)
Самая простая конвейерная лента - та, которая просто принимает входные данные и всегда переходит к следующему выражению. Вот что такое «трубопровод».
Другая возможность, это позволить ему пройти через следующую машину, если для значения выполнено какое-то условие. Это означает, что если в некоторых промежуточных выражениях значение меняется на то, что больше не разрешено, то остальные выражения будут пропущены. Это то, что делает монада «Возможно» в Хаскеле.
Вы также можете выполнять другие необычные правила копирования / изменения значений до или после их передачи на компьютер. Пример: парсеры (здесь, если выражение возвращает результат «сбой», значение перед выражением используется в качестве вывода).
Конечно, аналогия не идеальна, но я надеюсь, что она дает хорошее представление о том, как работают монады.
Однако у меня много проблем, чтобы перевернуть эту аналогию с ног на голову, чтобы понять Comonads. Из небольшого количества информации, которую я нашел в Интернете, я знаю, что Comonad определяет:
extractЭто своего рода обратная сторонаreturn, то есть она берет значение из Comonad.duplicate, что является своего рода обратнымjoin, то есть он создает две Comonads из одного.
Но как создать экземпляр Comonad, если мы можем только извлечь из них или продублировать их? И как они на самом деле могут быть использованы? Я видел этот очень удивительный проект и разговоры о нем (о которых я, к сожалению, очень мало понимал), но я не уверен, какую именно часть функций обеспечивает Comonad.
Что такое Comonad? Для чего они полезны? Как их можно использовать? Они съедобны?
IOмонады, это система времени исполнения Haskell, которая вызывает main. Там тоже unsafePerformIO, конечно. Если вы хотите думать о Maybeмонаде как о «машине на конце конвейерной ленты», вы можете использовать ее maybe.
cobindприложений, должна быть какая-то функция, которая делает что-то полезное с внутренним представлением вашей комонады.