diff options
author | Konrad Hinsen <konrad.hinsen@laposte.net> | 2009-02-10 10:28:45 +0000 |
---|---|---|
committer | Konrad Hinsen <konrad.hinsen@laposte.net> | 2009-02-10 10:28:45 +0000 |
commit | a812b031e595baeae00034b3f3b54f78a813a6a6 (patch) | |
tree | 6785e0fd55b852934d4c3146c57b1908b9cc03d1 /src/clojure | |
parent | c7560960f5315df096d00bf7c9500e3588c76aa8 (diff) |
monads: optimization in domonad
Diffstat (limited to 'src/clojure')
-rw-r--r-- | src/clojure/contrib/monads.clj | 24 |
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 |