【问题标题】:Use for the identity monad in Clojure用于 Clojure 中的身份单子
【发布时间】:2010-08-17 18:44:49
【问题描述】:
我一直在阅读excellent introduction to monads for Clojure programmers。文章说明 Identity monad 在功能上等同于 Clojure 的 let,而 Sequence/List monad 等同于 for。
当文章谈到 monad 转换器时,它展示了一个结合 Maybe 和 Sequence monad 的示例。好的,所以使用 Sequence monad 而不是 for 的一个原因是我可以转换它。但是,转换 Identity monad 对我来说没有意义——这不总是等同于构建转换 monad 的任何东西吗?例如,如果我用 Identity 转换了 Maybe - 那不只是给了我一个 Maybe,这会更容易直接声明吗?
有人可以澄清在 Clojure 中是否有实际用途来选择 Identity monad 而不是 let(也许我并没有完全考虑变压器?),还是只是为了理论上的完整性?
【问题讨论】:
标签:
clojure
monads
clojure-contrib
【解决方案1】:
确实,identity monad 作为 monad 转换器的基础非常有用。例如,maybe monad 转换器 (maybe-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
请注意,使用 Maybe-m 作为基础 monad 会同时使用 :fail 和 nil,而不仅仅是 :fail。
【解决方案2】:
一个很好的理由是您可以编写不绑定到特定 monad 的 monadic 函数,然后在 with-monad 块中执行它们。如果你写(with-monad identity-m ...),identity-m 让你可以选择不涉及任何特殊的一元巫术。
(很明显,如果你的 monadic 函数必须使用它所使用的 monad 的某些属性,例如 getter 和 setter 的可用性等,这将不起作用。然而,并非所有的 monadic 函数都是这样的.)