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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en