I originally posted this in Stack Overflow<http://stackoverflow.com/questions/19505334/clojure-algo-monad-strange-m-plus-behaviour-with-parser-m-why-is-second-m-plus>, but realised I might get more response from the google group. Apologies for duplication.
I'm seeing some issues using a parser monad created from the state monad transformer. I've written a full test case on the SO page outlining the issue, which is that when I use m-plus for the combined monad, it always evaluates the first 2 methods, even though it uses the return values from the first (if it is valid), and any state changes in the second occur but are discarded (however side effects do - like d/b updates etc). e.g. (def parser-m (state-t maybe-m)) (def world-destroyer (domonad parser-m [_ (fetch-state) result (m-plus (check-we-are-chilled) (destroy-planet))] result)) (world-destroyer {:chill-out true}) In this implementation, destroy-planet is always evaluated. Both of these monadic functions can terminate by using a :when condition on the state. If I add a dummy method to the m-plus call list at the start (as first or as second method in list) that does nothing (using a :when nil predicate to stop its evaluation), the results are fine, no planet is destroyed because it's never called, and the dummy monadic function takes the hit of stopping m-plus spilling into the destroy-planet function. Interestingly, any state changes I make in the method erroneously called do not get reflected in the final return value (clearly due to immutability of the state map), but side effects are happening - and that's my issue. I've reverted to using a hand-crafted parser-m as given on Jim Duey's monad blog <http://www.intensivesystems.net/tutorials/monads_101.html> which doesn't exhibit this behaviour. I'm relatively inexperienced with clojure and monads (I was using this as an excuse to learn them both), so I thought i'd try and work out why it's happening. >From looking at the definitions of state-t monad-m, the only thing i can see m-plus doing different to Jim's version is: state-t monad-m: (defn x [s] (apply (fn [& xs] (first (drop-while nil? xs))) (map #(% s) flist))) jim's: (defn y [s] (first (drop-while nil? (map #(% s) flist)))) for some list of functions flist, e.g. (def flist [(fn [x] (println "f a : " x) (when-let [r (:a x)] r)) (fn [x] (println "f b: "x) (when-let [r (:b x)] r)) (fn [x] (println "f nil : " x) nil)]) (x {:b 2}) (y {:b 2}) and running either of these produces same result (2), however they both produce the println side effects of *all 3* functions in the list, so now i'm even more confused. I thought everything in y is lazy, so only the first two methods would be used from the array. I can't find anything saying apply is lazy, so thought I was getting closer. Anyone have any thoughts on this? Am I using m-plus in the right way inside a domonad call? Cheers, Mark -- -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.