Konrad,
I did some more work from the paper the parser combinator is based
on. From that I built what I think is a state monad transformer:
(defn stateT [m]
(monad [m-result (fn [v]
(fn [s]
((:m-result m) (list v s))))
m-bind (fn [stm f]
(fn [s]
((:m-bind m) (stm s)
(fn [[v ss]]
((f v) ss)))))
m-zero (when (:m-zero m)
(fn [s]
(:m-zero m)))
m-plus (when (:m-plus m)
(fn [& stms]
(fn [s]
(apply (:m-plus m)
(map #(% s) stms)))))
]))
This function takes a monad and wraps it inside a state monad,
producing a new monad with a combination of characteristics from both.
I also rewrote the maybe monad as:
(defmonad maybe
"Monad describing computations with possible failures. Failure is
represented by an empty vector, success by a vector with a single
element, the resulting value."
[m-zero []
m-result (fn [v]
[v])
m-bind (fn [vs f]
(into [] (mapcat f vs)))
m-plus (fn [& mvs]
(let [first-valid (first (drop-while empty? mvs))]
(if (nil? first-valid)
m-zero
first-valid)))
])
(notice the change to the bind function).
This let me write the parser monad as:
(def parser-m (stateT maybe))
If that stateT function isn't actually a monad transformer, it still
is a slick way of combining the two monads.
Jim
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---