diff options
-rw-r--r-- | src/clojure/contrib/monads.clj | 19 | ||||
-rw-r--r-- | src/clojure/contrib/monads/examples.clj | 12 |
2 files changed, 22 insertions, 9 deletions
diff --git a/src/clojure/contrib/monads.clj b/src/clojure/contrib/monads.clj index e2fc0fca..3b803580 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 March 20, 2009 +;; last updated March 24, 2009 ;; Copyright (c) Konrad Hinsen, 2009. All rights reserved. The use ;; and distribution terms for this software are covered by the Eclipse @@ -59,9 +59,9 @@ monad comprehension expression mexpr." [mexpr step] (let [[bform expr] step] - (if (identical? bform :when) - `(if ~expr ~mexpr ~'m-zero) - (list 'm-bind expr (list 'fn [bform] mexpr))))) + (cond (identical? bform :when) `(if ~expr ~mexpr ~'m-zero) + (identical? bform :let) `(let ~expr ~mexpr) + :else (list 'm-bind expr (list 'fn [bform] mexpr))))) (defn- monad-expr "Transforms a monad comprehension, consisting of a list of steps @@ -101,10 +101,13 @@ "Monad comprehension. Takes the name of a monad, a vector of steps given as binding-form/monadic-expression pairs, and a result value specified by expr. The monadic-expression terms can use the binding - variables of the previous steps. If the monad contains a definition - of :zero, the step list can also contain conditions of the form [:when p], - where the predicate p can contain the binding variables from all previous - steps." + variables of the previous steps. + If the monad contains a definition of m-zero, the step list can also + contain conditions of the form :when p, where the predicate p can + contain the binding variables from all previous steps. + A clause of the form :let [binding-form expr ...], where the bindings + are given as a vector as for the use in let, establishes additional + bindings that can be used in the following steps." ([steps expr] (monad-expr steps expr)) ([name steps expr] diff --git a/src/clojure/contrib/monads/examples.clj b/src/clojure/contrib/monads/examples.clj index 850fc19d..a216cb39 100644 --- a/src/clojure/contrib/monads/examples.clj +++ b/src/clojure/contrib/monads/examples.clj @@ -43,12 +43,22 @@ y (range 3)] (+ x y))) +; Conditions are written with :when, as in Clojure's for form: (domonad sequence-m [x (range 5) y (range (+ 1 x)) - :when (= (+ x y) 2)] + :when (= (+ x y) 2)] (list x y)) +; :let is also supported like in for: +(domonad sequence-m + [x (range 5) + y (range (+ 1 x)) + :let [sum (+ x y) + diff (- x y)] + :when (= sum 2)] + (list diff)) + ; An example of a sequence function defined in terms of a lift operation. (with-monad sequence-m (defn pairs [xs] |