Commits

Meikel Brandmeyer committed 0bc18ec

Use different tags and multimethods for Maybe monad

* monad/maybe.clj (from-maybe,bind): rewrite as multimethods and
use ::nothing resp. ::just as dispatch tag.

* monad/maybe.clj (nothing, just, is-nothing?, is-just?):
use the new type tags.

Comments (0)

Files changed (1)

src/de/kotka/monad/maybe.clj

 
 (defvar
   nothing
-  (return ::type `nothing)
+  (return ::nothing `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 ::just something))
 
 (defn is-nothing?
   "Predicate for testing, whether a given monad represents nothing."
   [m]
-  (= `nothing (monad m)))
+  (= (monad-type m) ::nothing))
 
-(defvar
-  is-just?
-  (complement is-nothing?)
-  "Predicate for testing, whether a given monad represents some value.")
+(defn is-just?
+  "Predicate for testing, whether a given monad represents some value."
+  [m]
+  (= (monad-type m) ::just))
 
-(defn from-maybe
+(defmulti
+  #^{:arglists '[(monad) (monad default)]
+     :doc
   "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)
-     (monad m)
-     (throw (Exception. "Tried to retrieve a value from nothing"))))
-  ([m default]
-   (if (is-just? m) (monad m) default)))
+  represents nothing. Or throws an exception in case no default was given."}
+  from-maybe
+  #(monad-type %))
 
-(defmethod bind ::type
+(defmethod from-maybe ::just
+  [m & _]
+  (monad m))
+
+(defmethod from-maybe ::nothing
+  ([_]
+   (throw (Exception. "Tried to retrieve a value from nothing")))
+  ([_ default]
+   default))
+
+(defmethod bind ::just
   [m f]
-  (let [m (monad m)]
-    (if (= `nothing m) m (f m))))
+  (f (monad m)))
+
+(defmethod bind ::nothing
+  [m _]
+  m)