2010-08-16 32 views
10

我一直在阅读excellent introduction to monads for Clojure programmers。该文章说明Identity monad在功能上等同于Clojure的,并且序列/列表monad相当于对于用于Clojure身份monad

当文章到达monad变换器时,它将显示一个结合Maybe和Sequence monads的示例。好吧,所以使用序列monad而不是的的一个原因是我可以转换它。然而,改变一个身份monad对我来说没有意义 - 这不就等于只是建立变换monad的东西吗?例如,如果我将Maybe与Identity一起转换 - 是不是只给了我一个Maybe,这会更容易直接声明?

可有人清理是否有实际用途Clojure中选购身份单子在(也许是我没有想到一路过关斩将变压器的含义是什么?),还是只是有为了理论上的完整性?

回答

7

一个很好的理由是,你可以编写不与特定monad绑定的monadic函数,然后在with-monad块中执行它们。 identity-m如果你写(with-monad identity-m ...),你可以选择不涉及任何特殊的一元巫术。 (很显然,如果你的monadic函数必须使用monad的某些属性,比如getter和setter的可用性等等,那么这将不起作用。并不是所有的monadic函数都是这样的,然而)

8

实际上,身份monad作为monad变换器的基础非常有用。例如在可能单子转换(也许-T)允许比零以外的任何值:

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为基础单子会快捷两个:失败和nil,而不是只:失败。