
If I am writing a rener/parser for e.g. HTTP Requests and Responses, I would like to be able to guarantee that the parser really is the inverse of the generator. I assume that if I define a pair of computations as reversible then I can put those computations in some monad such that I can do: parse = inverse generate and parse2 = inverse do {generate;generate2} Actually, I assume this is an arrow rather than a monad because a render is a computation that takes a value and produces a value rather than simply a computation that produces a value. Whether its an arrow or not, I also assume this problem is sufficiently common that there is a well worked out idiom for this such that I don't have to hand-code and prove inverse functions for all my data structures. I just don't know what it is. -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com

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
participants (1)
-
S. Alexander Jacobson