Недавно я стер свои знания о том, как работают монады. Я также был введен в понятие «комонадой» , которая описывается как обратный двойной монады . Тем не менее, я не могу обернуть голову вокруг этого.
Чтобы понять монады, я сделал для себя аналогию:
Монады можно рассматривать как «план построения конвейерных выражений».
Чтобы определить новую 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
приложений, должна быть какая-то функция, которая делает что-то полезное с внутренним представлением вашей комонады.Ответы:
Комонада, как и монада, представляет собой математическую структуру в теории категорий. Со-префикс очень часто используется для обозначения «инверсий», как вы говорите (хотя я не думаю, что чистые математики согласны с выбором слова).
В теории категорий существуют
categories
, которые краткоobjects
обозначают совокупность (любого типа или природы, внутренняя структура не имеет значения) и некоторыеarrows
между этими объектами. Чтобы что-то было категорией, стрелки должны следовать некоторым законам (левая / правая идентичность и ассоциативность), но это не очень важно здесь.Теперь теория категорий очень абстрактна / трудна для понимания и обширна. Требуется много времени, чтобы пройти все это (и я не изучал это формально, я только знаю некоторые основы), но есть понятие, которое называется a
dual
. В принципе, для каждой категории вы можете создатьopposite category
, просто выполнив одно и то же, но «перевернув все стрелки». Это очень наивное определение, но трудно попытаться подвести итог. Двойственное что-то в категории C - это то же самое в противоположной категории C_op (головная боль еще есть?)В любом случае, если у вас есть монада над какой-то категорией (а категория может быть, например, категорией, в которой объекты являются типами в каком-то языке программирования, а стрелки - это функции между типами), то комонада - это в основном то же самое, только вы перевернули все стрелки (в данном случае это похоже на изменение сигнатур функций).
Более «практическое» описание (хотя и не СУПЕР-практическое) можно найти в этой дискуссии между Эриком Мейером и Брайаном Бекманом, где они обсуждают понятие дуальности и как Эрик делал «реверсирование стрелок»
IEnumerable<T>
в C #, когда создание реактивной структуры иIObservable<T>
(что, насколько я могу судить, и я рад, что меня исправили, в основном это экземпляр списка comonad).Другой практический пример комонад, упомянутых в видео, - это
Task<T>
тип в .NET, гдеTask<U> ContinueWith<U>(Func<Task<T>, U>)
будет двойной типbind
(илиSelectMany
как он называется в C #)источник
Из моего небольшого понимания, comonad - это машина Рубе Голдберга для постдоков:
http://www.willamette.edu/~fruehr/haskell/evolution.html
... извини, я не смог устоять перед этим.
источник