iteratee alternatives to MonadCatchIO
Bas van Dijk
v.dijk.bas at gmail.com
Thu Feb 10 12:54:39 GMT 2011
On 10 February 2011 09:03, John Lato <jwlato at gmail.com> wrote:
> Hello,
>
> Recently many projects have been switching from MonadCatchIO, because that
> library often doesn't do what users want in short-circuiting monads such as
> Error. I would like to know if there are any comments regarding iteratee
> switching to either monad-peel[0] or monad-control[1]. Currently it looks
> like monad-control is likely to supercede monad-peel in the near future as
> 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[2] with short-circuiting monads
> 2. faster?
>
> Contra:
> 1. Library is less stable, and less well understood
> 2. Client code may need to be re-written
>
> Thoughts?
>
> John
>
> [0] http://hackage.haskell.org/package/monad-peel
> [1] http://hackage.haskell.org/package/monad-control
> [2] 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:
http://www.mail-archive.com/haskell-cafe@haskell.org/msg77185.html
Note that I haven't verified that your instance is problematic but it
looks very much the same as the problematic ContT instance. Compare
them:
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.
Regards,
Bas
More information about the Iteratee
mailing list