
I think I just figured it out. Answering my own question and asking another: The property we want to fulfill is: prop_reverse forward reverse thing = roundtrip thing == thing where roundtrip = reverse . forward Since a function is a value that produces a computation (when evaluated) and a monad is a computation that (when executed) produces a value, we can assert that: monads are the dual of functions execution is the dual of evaluation So if monad "return" takes a value and brings it into the computation, we need a dual, e.g. "run", that takes a computation and produces a value. So we have our reverse monads also be instances of: class Runnable m a where run::m a -> a --example instance instance Runnable (Maybe a) where run = fromJust Now we can update the above property to be: prop_reverse forward reverse thing = roundtrip thing == thing where roundtrip = run . reverse . return . forward So if we have functions f and g, with reverse monads f' and g' respectively the following properties should hold: prop_reverse f f' prop_reverse g g' And, here is the payoff!!!! prop_reverse (f . g) (f' >>= g') So you can use these two very readable notations to e.g. render and parse data structures e.g. renderReq (Request m u v h b) = (render m . render u . render v . render h . render b) parseReq text = (m <- parse; u <- parse; v <- parse; h<-parse; b <- parse' contentLength) I'm a beginner (without much formal math training), so please correct if I am mistaken. But, assuming the above is correct, my updated question is in which library is cannonical equivalent of Runnable. I would have assumed it is in the Monad library, but nothing there looks like it. Instead all I can find are special purpose things like fromJust and even uglier stuff for Either. -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com