用于Clojure中的身份monad

时间:2010-08-16 04:23:45

标签: clojure monads clojure-contrib

我一直在读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 (也许我并没有考虑到变形金刚?),还是它只是为了理论上的完整性?

2 个答案:

答案 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函数都是这样的,但是。)