
On Sat, May 15, 2010 at 9:20 PM, Antoine Latter
On Fri, May 14, 2010 at 4:25 PM, Derek Elkins
wrote: You did it wrong. All you did was Church encode the Either type. Your bind is still doing a case-analysis. All you have to do is use ContT r (Either e). The bind implementation for ContT is completely independent of the underlying monad. It doesn't even require the m in ContT r m to be a functor, let alone a monad. Therefore the ContT bind doesn't do any case-analysis because it doesn't know anything about the underlying monad. One way to look at what is happening is to compare it to Andrzej Filiniski's work in "Representing Monads" and "Representing Layered Monads".
Here's a bit more fleshed out version of what Derek is talking about, for those following along at home:
http://hpaste.org/fastcgi/hpaste.fcgi/view?id=25515#a25515
Derek - should I be doing something smarter in 'catch'? I couldn't think of anything obvious.
No, that's pretty much what you should be doing also note, for conceptual purposes, that the const (Left e) is equivalent to (Left e
=). In "Representing Monads" to actually perform an effect it gets reified back into a data structure, in this case Either e a, manipulated as appropriate, then reflected back into an implicit effect. The reify function is just applying to the identity continuation so your catch can be written more clearly.
reify :: Monad m => ContT r m r -> m r reify m = runContT m return catch :: (e -> Error e a) -> Error e a -> Error e a catch handler m = case reify (unE m) of Left e -> handler e; Right a -> return a