Commits

Meikel Brandmeyer committed 2d7bc43

Reworked (again) the monad representation

* monad.clj (return): now returns a wrapper structure
(monad): new function

* maybe.clj: adapted to new representation

  • Participants
  • Parent commits ca065b4

Comments (0)

Files changed (2)

File src/de/kotka/monad.clj

 ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 ; THE SOFTWARE.
 
-(clojure.core/ns de.kotka.monad)
+(clojure.core/ns de.kotka.monad
+  (:use
+     [clojure.contrib.def :only (defstruct-)]))
+
+(defstruct- monad-structure :type :monad)
 
 (defn return
   "Bless an object with the given monad type."
   [t m]
-  (with-meta m (assoc (meta m) ::monad t)))
+  (struct monad-structure t m))
+
+(defn monad
+  "Return the monad of a blessed object."
+  [m]
+  (m :monad))
 
 (defmulti
   #^{:doc
   "bind makes the value of the given monad available to a function.
   The function may act on the value, but it must return another monad.
   Although this cannot be enforced in Clojure."}
-  bind (fn [m _] (-> m meta ::monad)))
+  bind (fn [m _] (m :type)))
 
 (defmacro let-bind
   "let-bind binds the result of the given monads to the given variables

File src/de/kotka/monad/maybe.clj

      de.kotka.monad
      [clojure.contrib.def :only (defvar)]))
 
-(def
-  #^{:doc
-  "nothing represents the empty value of the maybe monad."}
+(defvar
   nothing
-  (return ::type `nothing))
+  (return ::type `nothing)
+  "nothing represents the empty value of the maybe monad.")
 
 (defn just
   "just returns a monad representing the passed-in something."
   [something]
-  (return ::type [something]))
+  (return ::type something))
 
 (defn is-nothing?
   "Predicate for testing, whether a given monad represents nothing."
   [m]
-  (= `nothing m))
+  (= `nothing (monad m)))
 
-(def
-  #^{:doc
-  "Predicate for testing, whether a given monad represents some value."}
+(defvar
   is-just?
-  vector?)
+  (complement is-nothing?)
+  "Predicate for testing, whether a given monad represents some value.")
 
-(defn from-maybe?
+(defn from-maybe
   "Retrieve the value from a maybe monad. Returns the default in case the monad
   represents nothing. Or throws an exception in case no default was given."
   ([m]
    (if (is-just? m)
-     (first m)
+     (monad m)
      (throw (Exception. "Tried to retrieve a value from nothing"))))
   ([m default]
-   (if (is-just? m) (first m) default)))
+   (if (is-just? m) (monad m) default)))
 
 (defmethod bind ::type
   [m f]
-  (if (= `nothing m) m (f (first m))))
+  (let [m (monad m)]
+    (if (= `nothing m) m (f m))))