On Sun, Oct 17, 2010 at 1:04 PM, Arie Peterson <ar...@xs4all.nl> wrote: > On Thu, 14 Oct 2010 12:01:59 +0200, Michael Snoyman > <mich...@snoyman.com> wrote: >> [...] which I believe is a flawed >> design in the MonadCatchIO-transformers package. Here are my thoughts >> on this and what I think needs to be done to fix it. >> >> [...] >> >> Try running the code with each version of go uncommented. In the first >> two, "sequel called" gets printed. However, in the third, it does not. >> The reason is short-circuiting: if we remember from the definition of >> finally, there are two cases we account for. If an exception is >> called, catch addresses it. If not, we assume that the next line will >> be called. However, in the presence of short-circuiting monads like >> ErrorT, that line of code will never get called! > > Yes. That is the behaviour I would expect. > > There are two kinds of exceptional values in, for instance, 'ErrorT e > IO a': > • IO exceptions, in the "underlying monad" 'IO'; > • error values of type 'e', in the monad transformer 'ErrorT e'. > The MonadCatchIO instance for ErrorT deals with the first kind only. > Catching IO exceptions, and cleaning up after them, is what MonadCatchIO > was invented for. I feel that I should not decide for all users how > these two layers of exceptions should interact; keeping the MonadCatchIO > instance oblivious to the underlying monad as much as possible seems > like the safest/most general thing to do. > > Meanwhile, I can see why you would want 'finally' to also catch the > ErrorT errors, in your example, and circumvent the short-circuiting. > However, I'm not convinced that this is always the right (expected, most > useful, ...) behaviour. Maybe I just need more convincing :-). >
I think the big thing I would look for is that the second argument to 'finally' always run (barring calls to System.Exit or the universe ending or whatever). Otherwise I wouldn't expect any other interaction with the 'Left' half of ErrorT. For example I wouldn't expect the 'error' half of 'try' to be run on Left, but I would expect the cleanup tasks in 'bracket' to be executed. Otherwise the function just isn't useful. Antoine _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe