1

观看本教程后,我正在研究自己的一些示例:http: //www.infoq.com/presentations/Why-is-a-Monad-Like-a-Writing-Desk并阅读http://blog。 sigfpe.com/2006/08/you-could-have-invented-monads-and.html

我想出了以下功能:

(定义单位 [vs]
  (fn [] [vs]))

(定义绑定 [mv f]
  (f (mv)))

(定义公司+ [mv]
  (绑定
   MV
   (fn [[对]]
     (让 [r (inc v)]
       (unit r (apply str (concat s "inc+(" (str r) ")")))))))

(定义双+ [mv]
  (绑定
   MV
   (fn [[对]]
     (让 [r (* 2 v)]
       (unit r (apply str (concat s " double+(" (str r) ")")))))))

(定义三重+ [mv]
  (绑定
   MV
   (fn [[对]]
     (让 [r (* 3 v)]
       (unit r (apply str (concat s " triple+(" (str r) ")")))))))

;; 测试:

((-> (unit 1 "1 ->") inc+))
;; => [2 "1 -> 公司+(2)"]


((-> (unit 3 "3 ->") inc+ double+ inc+))
;; => [27 "3 -> inc+(4) double+(8) inc+(9) Triple+(27)"]

我希望重写 bind 以封装 inc+ double+ 和 Triple+ 方法的模式,并获得与以前相同的输出。这将如何完成?

4

1 回答 1

1

我分两个阶段弄清楚:

(定义单位 [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调用。binddo-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)"]
于 2012-09-08T00:38:48.633 回答