我分两个阶段弄清楚:
(定义单位 [vs]
(fn [] [vs]))
(定义绑定 [mv f]
(让 [[iv 是] (mv)
[av as] (f iv)]
(单位 av (str is " " as))))
(定义公司+ [mv]
(绑定
MV
(fn [v]
[(inc v) (str "inc+(" (inc v) ")")])))
(定义双+ [mv]
(绑定
MV
(fn [v]
[(inc v) (str " double+(" (inc v) ")")])))
(定义三重+ [mv]
(绑定
MV
(fn [v]
[(inc v) (str " Triple+(" (inc v) ")")])))
然后:
(定义单位 [vs]
(fn [] [vs]))
(定义绑定 [mv f]
(让 [[vs] (mv)
r (fv)
xs (->> (str (type f))
(重新找#"\$([^\$]*)\$?")
第二) ]
(单位 r (str s " " (str xs "(" r ")")))))
(定义公司+ [mv]
(绑定 mv inc))
(定义双+ [mv]
(绑定 mv #(* 2 %)))
(定义三重+ [mv]
(绑定 mv #(* 3 %)))
((-> (unit 3 "3 ->") inc+ double+ inc+ Triple+))
;;=> [27 "3 -> inc_PLUS_(4) double_PLUS_(8) inc_PLUS_(9) Triple_PLUS_(27)"]
因此,查看其他 Monad 教程,尤其是http://channel9.msdn.com/Shows/Going+Deep/Brian-Beckman-Dont-fear-the-Monads,我想我现在了解了核心原则。'Monads' 真的是关于能够重用我们手头的功能。unit
并且bind
必须设计为可以协同工作。然后,将函数组合在一起几乎是微不足道的。
然后再抽象一个写do-m
操作符:
(定义单位 [vs]
(fn [] [vs]))
(定义绑定 [mv f]
(让 [[vs] (mv)
r (fv)
xs (->> (str (type f))
(重新找#"\$([^\$]*)\$?")
第二) ]
(单位 r (str s " " (str xs "(" r ")")))))
(定义双 [v] (* 2 v))
(定义三元组 [v] (* 3 v))
(defn do-m [v & fs]
(let [fn-ms (map #(fn [mv] (bind mv %)) fs)]
((((apply comp (reverse fn-ms)) (unit v (str v "->"))))))
(do-m 3 inc 双三倍)
;;=> [24 "3 -> inc(4) double(8) Triple(24)"]
这是实现相同结果的另一种编写方式,请注意更改是取出 lambda 函数 in以及相关的andunit
调用。bind
do-m
(定义单位 [vs] [vs])
(定义绑定 [mv f]
(让 [[vs] mv
r (fv)
xs (->> (str (type f))
(重新找#"\$([^\$]*)\$?")
第二) ]
(单位 r (str s " " (str xs "(" r ")")))))
(定义双 [v] (* 2 v))
(定义三元组 [v] (* 3 v))
(defn sqrt [v] (数学/sqrt v))
(defn do-m [v & fs]
(let [fn-ms (map #(fn [mv] (bind mv %)) fs)]
(((apply comp (reverse fn-ms)) (unit v (str v "->")))))
(do-m 3 inc 双双三三平方)
;; => [12.0 "3 -> inc(4) 双(8) 双(16) 三重(48) 三重(144) sqrt(12.0)"]