我一直在读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 中是否有实际用途选择一个身份monad而不是 let (也许我并没有考虑到变形金刚?),还是它只是为了理论上的完整性?
答案 0 :(得分:8)
事实上,身份monad作为monad变换器的基础非常有用。例如,monad变换器(也许-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。
答案 1 :(得分:7)
一个很好的理由是你可以编写与特定monad无关的monadic函数,然后在with-monad
块中执行它们。 identity-m
如果你写(with-monad identity-m ...)
,你可以选择不涉及任何特殊的monadic voodoo。
(显然,如果你的monadic函数必须使用它所使用的monad的某些属性,比如getter的可用性和状态的setter等,这将不起作用。并非所有的monadic函数都是这样的,但是。)