(ns cont-m-tutorial (:use clojure.contrib.monads)) (defn func-a [x] (inc x)) (defn func-b [x] (* 2 x)) (defn func-c [x] (dec x)) (defn fn1 [x] (let [a (func-a x) b (func-b a) c (func-c b)] c)) (fn1 10) (defn func-b [x f] (f (* 2 x))) (defn fn2 [x] (let [a (func-a x) c (func-b a func-c)] c)) (fn2 10) (defn func-a [x f] (f (inc x))) (defn cont-a [x] (func-b x func-c)) (defn fn3 [x] (let [c (func-a x cont-a)] c)) (fn3 10) (defn fn3 [x] (func-a x cont-a)) (fn3 10) (defn func-c [x f] (f (dec x))) (defn cont-b [x] (func-c x identity)) (defn cont-a [x] (func-b x cont-b)) (defn fn4 [x] (func-a x cont-a)) (fn4 10) (defn fn5 [x f] (f (func-a x cont-a))) (fn5 10 identity) (defn fn6 [x f] (let [cont-b (fn [x] (func-c x f)) cont-a (fn [x] (func-b x cont-b))] (func-a x cont-a))) (fn6 10 identity) (defn mf-a [x] (fn [c] (c (inc x)))) (defn mf-b [x] (fn [c] (c (* 2 x)))) (defn mf-c [x] (fn [c] (c (dec x)))) (with-monad cont-m (assert (= 21 ((m-result 21) identity))) (assert (= 22 ((m-bind (m-result 21) mf-a) identity))) (assert (= 44 ((m-bind (m-bind (m-result 21) mf-a) mf-b) identity))) (assert (= 44 ((m-bind (m-result 21) (m-chain [mf-a mf-b])) identity))) (def fn7 (m-chain [mf-a mf-b mf-c])) ((fn7 10) identity) (defn mf-a [x] (println "starting mf-a") (fn [c] (println "completing mf-a") (c (inc x)))) (defn mf-b [x] (println "starting mf-b") (fn [c] (println "completing mf-b") (c (* 2 x)))) (defn mf-c [x] (println "starting mf-c") (fn [c] (println "completing mf-c") (c (dec x)))) (def fn8 (m-chain [mf-a mf-b mf-c])) ((fn8 10) identity) (println) (defn halt [x] (fn [c] x)) (def fn9 (m-chain [mf-a halt mf-b mf-c])) ((fn9 10) identity) (println) (defn bounce [x] (fn [c] (fn [] (println "bounce") (c x)))) (def fn10 (m-chain [mf-a bounce mf-b bounce mf-c])) (trampoline ((fn10 10) identity)) (println) (defn mark [x] (fn [c] c)) (def mark-cont ((fn11 10) identity)) (doall (map mark-cont [0 1 2])) )