aboutsummaryrefslogtreecommitdiff
path: root/src/clojure
diff options
context:
space:
mode:
authorKonrad Hinsen <konrad.hinsen@laposte.net>2009-02-10 10:28:45 +0000
committerKonrad Hinsen <konrad.hinsen@laposte.net>2009-02-10 10:28:45 +0000
commita812b031e595baeae00034b3f3b54f78a813a6a6 (patch)
tree6785e0fd55b852934d4c3146c57b1908b9cc03d1 /src/clojure
parentc7560960f5315df096d00bf7c9500e3588c76aa8 (diff)
monads: optimization in domonad
Diffstat (limited to 'src/clojure')
-rw-r--r--src/clojure/contrib/monads.clj24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/clojure/contrib/monads.clj b/src/clojure/contrib/monads.clj
index 2f89cb76..72e6199d 100644
--- a/src/clojure/contrib/monads.clj
+++ b/src/clojure/contrib/monads.clj
@@ -1,7 +1,7 @@
;; Monads in Clojure
;; by Konrad Hinsen
-;; last updated January 29, 2009
+;; last updated February 10, 2009
;; Copyright (c) Konrad Hinsen, 2009. All rights reserved. The use
;; and distribution terms for this software are covered by the Eclipse
@@ -73,9 +73,19 @@
[steps expr]
(when (odd? (count steps))
(throw (Exception. "Odd number of elements in monad comprehension steps")))
- (reduce add-monad-step
- (list 'm-result expr)
- (reverse (partition 2 steps))))
+ (let [rsteps (reverse (partition 2 steps))
+ [lr ls] (first rsteps)]
+ (if (= lr expr)
+ ; Optimization: if the result expression is equal to the result
+ ; of the last computation step, we can eliminate an m-bind to
+ ; m-result.
+ (reduce add-monad-step
+ ls
+ (rest rsteps))
+ ; The general case.
+ (reduce add-monad-step
+ (list 'm-result expr)
+ rsteps))))
(defmacro with-monad
"Evaluates an expression after replacing the keywords defining the
@@ -278,11 +288,11 @@
"Monad describing computations in continuation-passing style. The monadic
values are functions that are called with a single argument representing
the continuation of the computation, to which they pass their result."
- [m-result (fn [v]
+ [m-result (fn m-result-cont [v]
(fn [c] (c v)))
- m-bind (fn [mv f]
+ m-bind (fn m-bind-cont [mv f]
(fn [c]
- (mv (fn [a] ((f a) c)))))
+ (mv (fn [v] ((f v) c)))))
])
(defn run-cont