aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/monads
diff options
context:
space:
mode:
authorKonrad Hinsen <konrad.hinsen@laposte.net>2009-01-29 15:50:06 +0000
committerKonrad Hinsen <konrad.hinsen@laposte.net>2009-01-29 15:50:06 +0000
commit054b9e79f925aaca268db0e67eead65e6dec93a6 (patch)
treefd049d3675f9ae49cb6bcd180136445a372d4196 /src/clojure/contrib/monads
parent53ceb892205b55ae64f396449454d8b932c8a757 (diff)
monads.clj: new cont monad, new macros m-when and m-when-not
Diffstat (limited to 'src/clojure/contrib/monads')
-rw-r--r--src/clojure/contrib/monads/examples.clj48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/clojure/contrib/monads/examples.clj b/src/clojure/contrib/monads/examples.clj
index 89b9bb68..98ffaecd 100644
--- a/src/clojure/contrib/monads/examples.clj
+++ b/src/clojure/contrib/monads/examples.clj
@@ -346,4 +346,52 @@
; The outcome of any function applied to arguments of which at least one
; is nil is supposed to be nil as well, and the function is never called.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Continuation-passing style in the cont monad
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; A simple computation performed in continuation-passing style.
+; (m-result 1) returns a function that, when called with a single
+; argument f, calls (f 1). The result of the domonad-computation is
+; a function that behaves in the same way, passing 3 to its function
+; argument. run-cont executes a continuation by calling it on identity.
+(run-cont
+ (domonad cont
+ [x (m-result 1)
+ y (m-result 2)]
+ (+ x y)))
+
+; Let's capture a continuation using call-cc. We store it in a global
+; variable so that we can do with it whatever we want. The computation
+; is the same one as in the first example, but it has the side effect
+; of storing the continuation at (m-result 2).
+(def continuation nil)
+
+(run-cont
+ (domonad cont
+ [x (m-result 1)
+ y (call-cc (fn [c] (def continuation c) (c 2)))]
+ (+ x y)))
+
+; Now we can call the continuation with whatever argument we want. The
+; supplied argument takes the place of 2 in the above computation:
+(run-cont (continuation 5))
+(run-cont (continuation 42))
+(run-cont (continuation -1))
+
+; Next, a function that illustrates how a captured continuation can be
+; used as an "emergency exit" out of a computation:
+(defn sqrt-as-str [x]
+ (call-cc
+ (fn [k]
+ (domonad cont
+ [_ (m-when (< x 0) (k (str "negative argument " x)))]
+ (str (. Math sqrt x))))))
+
+(run-cont (sqrt-as-str 2))
+(run-cont (sqrt-as-str -2))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;