iteratee alternatives to MonadCatchIO
jwlato at gmail.com
Thu Feb 10 15:32:23 GMT 2011
On Thu, Feb 10, 2011 at 12:54 PM, Bas van Dijk <v.dijk.bas at gmail.com> wrote:
> On 10 February 2011 09:03, John Lato <jwlato at gmail.com> wrote:
> > Hello,
> > Recently many projects have been switching from MonadCatchIO, because
> > library often doesn't do what users want in short-circuiting monads such
> > Error. I would like to know if there are any comments regarding iteratee
> > switching to either monad-peel or monad-control. Currently it
> > like monad-control is likely to supercede monad-peel in the near future
> > it is more performant, however it's very new and not as well understood.
> > As I see it:
> > Pro monad-control:
> > 1. exception handling Does The Right Thing with short-circuiting
> > 2. faster?
> > Contra:
> > 1. Library is less stable, and less well understood
> > 2. Client code may need to be re-written
> > Thoughts?
> > John
> >  http://hackage.haskell.org/package/monad-peel
> >  http://hackage.haskell.org/package/monad-control
> >  I've always expected the behavior provided by MonadCatchIO, and some
> > client code may rely upon it, so I'm not convinced it's a universal good.
> > _______________________________________________
> > Iteratee mailing list
> > Iteratee at projects.haskell.org
> > http://projects.haskell.org/cgi-bin/mailman/listinfo/iteratee
> Hi John,
> I think you are in a bit of trouble. Your continuation-based Iteratee
> instance for MonadCatchIO will probably result in the same unexpected
> behavior as described in:
> Note that I haven't verified that your instance is problematic but it
> looks very much the same as the problematic ContT instance. Compare
> m `catch` f = ContT $ \c -> runContT m c `catch` \e -> runContT (f e) c
> m `catch` f = Iteratee $ \od oc -> runIter m od oc `catch` (\e ->
> runIter (f e) od oc)
> To quote the thread: "...that code takes the continuation to run after
> the block, c, and runs that inside the catch block..."
> If I'm not mistaken, what basically happens in a continuation-based
> monad is that the following:
> (m `catch` \e -> h e) >>= f
> is transformed into:
> m >>= f `catch` \e -> h e >>= f
> This is problematic if f and h both perform the same finalizer, as is
> the case in bracket, because that finalizer will now be performed
> twice (or even 3 times if 'h e' does not rethrow the exception).
> The conclusion of the thread was that the ContT instance needs to be
> removed from MonadCatchIO. monad-peel and monad-control don't provide
> an instance for ContT for the same reason. So I believe you need to
> remove your MonadCatchIO instance.
> The question is, what is the alternative? I have no answer yet.
It does look like this affects the iteratee MonadCatchIO instance, but I
think this may not actually be a big problem. Iteratees are generally the
top level of any monad stack (at least this holds for my code), so I don't
believe removing the MonadCatchIO instance will affect many (any?) users.
What's important is that we have a means to handle exceptions within the
underlying monad stack for enumHandle etc., and any of these libraries will
handle that to some extent. Although this would put a crimp in one of
Oleg's clever tricks...
It would mean that it's no longer possible to use the standard "enum*"
functions with a ContT as part of the stack, but that can break things
anyway. My attitude thus far has been that if you're playing tricks with
ContT, you deserve what you get.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Iteratee