I'm writing a maybe/state monad using clojure.contrib.monads. I've
gotten by fine with using just (state-t maybe-m), but now I need
different behavior:
  I need a monad that behaves precisely like (state-t maybe-m), except
that when a monadic value mv is called on a state s and fails, (mv s)
returns [::failure s] *instead of nil* (as maybe-m normally does).
This is the difference.

Now I'm basically done, except I can't figure out a value of m-zero
that fulfills the required axioms:
  - (m-bind m-zero f) produces m-zero
  - (m-bind mv (fn [x] m-zero)) produces m-zero

This is what I have so far:

  (defmonad parser-m
    "The monad that FnParse uses."
    [m-zero (fn [state] [::failure state])
     m-result (fn m-result-parser [product]
                (fn [state] [product state]))
     m-bind (fn m-bind-parser [rule product-fn]
              (fn [state]
                (let [result (rule state)]
                  (if (failure? result)
                    result
                    (let [[product new-state] result]
                      ((product-fn product) new-state))))))
     m-plus (fn m-plus-parser [& rules]
              (fn [state]
                (or (first (drop-while failure? (map #(% state)
rules)))
                    (m-zero state))))])

The first axiom is fulfilled:
user=> (def a (m-bind m-zero (constantly [5 [2 3]])))
#'user/a
user=> (a [0 1])
[:user/failure [0 1]]
user=> (m-zero [0 1])
[:user/failure [0 1]]

But the second is not:
user=> (def b (m-bind (constantly [:x [1 2]]) m-zero))
#'user/b
user=> (b [0 1])

And no matter what I do, I can't fulfill that second axiom. Has anyone
created this type of monad before? It seems like it should be a common
pattern: exactly like (state-t maybe-m), only failures are vector
pairs too.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to