aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKonrad Hinsen <konrad.hinsen@laposte.net>2009-03-20 10:46:17 +0000
committerKonrad Hinsen <konrad.hinsen@laposte.net>2009-03-20 10:46:17 +0000
commit0a694e70f36ce6986ec8b21846426ff17d3aabc2 (patch)
tree17fa66882941de556c28d4d26a29d005dfc3377f /src
parent19613025d233b5f445b1dd3460c4128f39218741 (diff)
monads: new state monad functions for working with maps
Diffstat (limited to 'src')
-rw-r--r--src/clojure/contrib/monads.clj35
-rw-r--r--src/clojure/contrib/monads/examples.clj2
2 files changed, 32 insertions, 5 deletions
diff --git a/src/clojure/contrib/monads.clj b/src/clojure/contrib/monads.clj
index 01ee7784..e2fc0fca 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 6, 2009
+;; last updated March 20, 2009
;; Copyright (c) Konrad Hinsen, 2009. All rights reserved. The use
;; and distribution terms for this software are covered by the Eclipse
@@ -261,7 +261,7 @@
"Monad describing stateful computations. The monadic values have the
structure (fn [old-state] (list result new-state))."
[m-result (fn m-result-state [v]
- (fn [s] (list v s)))
+ (fn [s] [v s]))
m-bind (fn m-bind-state [mv f]
(fn [s]
(let [[v ss] (mv s)]
@@ -269,14 +269,41 @@
])
(defn update-state [f]
- (fn [s] (list s (f s))))
+ "Return a state-monad function that replaces the current state by the
+ result of f applied to the current state and that returns the old state."
+ (fn [s] [s (f s)]))
(defn set-state [s]
+ "Return a state-monad function that replaces the current state by s and
+ returns the previous state."
(update-state (fn [_] s)))
(defn fetch-state []
+ "Return a state-monad function that returns the current state and does not
+ modify it."
(update-state identity))
+(defn fetch-val [key]
+ "Return a state-monad function that assumes the state to be a map and
+ returns the value corresponding to the given key. The state is not modified."
+ (domonad state-m
+ [s (fetch-state)]
+ (key s)))
+
+(defn update-val [key f]
+ "Return a state-monad function that assumes the state to be a map and
+ replaces the value associated with the given key by the return value
+ of f applied to the old value. The old value is returned."
+ (fn [s]
+ (let [old-val (get s key)
+ new-s (assoc s key (f old-val))]
+ [old-val new-s])))
+
+(defn set-val [key val]
+ "Return a state-monad function that assumes the state to be a map and
+ replaces the value associated with key by val. The old value is returned."
+ (update-val key (fn [_] val)))
+
; Writer monad
(defn writer-m
"Monad describing computations that accumulate data on the side, e.g. for
@@ -404,7 +431,7 @@
(monad [m-result (with-monad m
(fn m-result-state-t [v]
(fn [s]
- (m-result (list v s)))))
+ (m-result [v s]))))
m-bind (with-monad m
(fn m-bind-state-t [stm f]
(fn [s]
diff --git a/src/clojure/contrib/monads/examples.clj b/src/clojure/contrib/monads/examples.clj
index 2d3dbb12..850fc19d 100644
--- a/src/clojure/contrib/monads/examples.clj
+++ b/src/clojure/contrib/monads/examples.clj
@@ -152,7 +152,7 @@
(let [m 259200
value (/ (float seed) (float m))
next (rem (+ 54773 (* 7141 seed)) m)]
- (list value next)))
+ [value next]))
; We define a convenience function that creates an infinite lazy seq
; of values obtained from iteratively applying a state monad value.