clojure中的序列monad查询

时间:2014-07-17 04:20:36

标签: clojure monads

我正试图在查询中围绕序列monad。

我有这个代码使用clojure.algo.monads创建一个序列monad:

(use 'clojure.algo.monads)

(def sequence-monad-decider
     (fn [step-value monadic-continuation]
       (mapcat monadic-continuation step-value)))

(def sequence-monad-monadifier list)

(def sequence-monad
     (monad [m-result sequence-monad-monadifier
             m-bind sequence-monad-decider]))

(prn
 (with-monad sequence-monad
   (domonad [a [1 2]
             b [10, 100]
             c [-1 1]]
            (* a b c))))

所以我理解m-bind将用于传递步长值和延续sequence-monad-decider

sequence.monad-decider的定义如下:

(def sequence-monad-decider
     (fn [step-value monadic-continuation]
       (mapcat monadic-continuation step-value)))

所以,如果我们看一下调用monad:

(prn
 (with-monad sequence-monad
   (domonad [a [1 2]
             b [10, 100]
             c [-1 1]]
            (* a b c))))

使用上述绑定a[1 2]将作为步骤值传递给sequence.monad.decider但是作为第二个参数传递的monadic-continuation函数是什么这个功能?

1 个答案:

答案 0 :(得分:1)

sequence-monad-decidersequence-monad-monadifier的更常见名称为bindresultreturnunit

(defn bind [mv f] (mapcat f mv)) 
(defn unit [v] [v])

然后

 (domonad sequence-m
   [a [1 2]
    b [10, 100]
    c [-1 1]]
   (* a b c))

 (bind [1 2] 
       (fn [a] 
         (domonad sequence-m
           [b [10, 100]
            c [-1 1]]
           (* a b c))))

试试吧!因此,你恰当地命名为monadic-continuation的第二个参数是monad的延续,其余的动作。

如果您执行此操作,则可以使用

完全放松
(bind [1 2]
      (fn [a] (bind [10 100]
                    (fn [b] (bind [-1 1]
                                  (fn [c] (unit (* a b c))))))))

domonad只是糖。您可以看到一个非常简单的实现at my answer here