Использовать для моноды с идентификатором в Clojure
Я читал отличное введение в монады для программистов Clojure. В статье показано, что монада Identity функционально эквивалентна Clojure let и что монада Sequence/List эквивалентна for.
Когда статья попадает на монадные трансформаторы, он показывает пример, объединяющий монады Maybe и Sequence. Итак, одна из причин использования монадии Sequence вместо a for заключается в том, что я могу ее преобразовать. Однако преобразование монады Идентичности для меня не имеет смысла - разве это не всегда было бы эквивалентно простому созданию любой преобразующей монады? Например, если я преобразовал Maybe with Identity - это не значит, что просто дайте мне Maybe, который было бы проще объявить напрямую?
Может ли кто-нибудь выяснить, есть ли практическое использование в Clojure для выбора монадии Identity над let (возможно, я не думаю полностью о последствиях трансформаторов?), или это просто теоретическая полнота
Ответы
Ответ 1
Одна хорошая причина заключается в том, что вы можете писать монадические функции, которые не привязаны к определенной монаде, а затем выполнять их в блоке with-monad
. identity-m
дает вам возможность не включать какой-либо особый монадический вуду, если вы пишете (with-monad identity-m ...)
.
(Ясно, что это не сработает, если ваша монадическая функция существенно использует некоторые свойства монады, с которой она работает, например, наличие геттера и сеттера для состояния и т.д. Не все монадические функции похожи на это.)
Ответ 2
Действительно, тождественная монада очень полезна как основа в монадном трансформаторе. Например, возможно, монадный трансформатор (возможно-t) допускает значение ничего, кроме nil:
1:2 => (use 'clojure.contrib.monads)
nil
1:3 => (domonad maybe-m [a 1 b 2] (+ a b))
3
1:4 => (domonad maybe-m [a 1 b nil] (+ a b))
nil
;; Domain uses the :fail keyword as the nil value:
1:6 => (domonad (maybe-t identity-m :fail) [a 1 b :fail] (+ a b))
:fail
Обратите внимание, что использование возможно-m в качестве базовой монады будет ярлык на обоих: fail и nil, а не просто: fail.