10

我一直在为 Clojure 程序员阅读关于 monad 的精彩介绍。这篇文章说明了 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是否有实际用途(也许我没有一直考虑变压器的含义?),还是只是为了理论上的完整性?

4

2 回答 2

8

事实上,身份单子作为单子转换器中的基础非常有用。例如,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。

于 2010-08-17T10:44:49.717 回答
7

一个很好的理由是您可以编写不绑定到特定 monad 的 monadic 函数,然后在一个with-monad块中执行它们。identity-m如果你写的话,你可以选择不涉及任何特殊的一元巫术(with-monad identity-m ...)

(显然,如果您的 monadic 函数必须使用与其一起工作的 monad 的某些属性,例如状态的 getter 和 setter 的可用性等,这将不起作用。然而,并非所有的 monadic 函数都是这样的。)

于 2010-08-16T04:32:12.850 回答