
Hi!
On Wed, Dec 1, 2010 at 10:50 AM, Simon Marlow
Yes, but semantics are different. I want to tolerate some exception because they are saying I should do this and this (for example user interrupt, or timeout) but I do not want others, which somebody else maybe created and I do not want to care about them.
Surely if you don't care about these other exceptions, then the right thing to do is just to propagate them? Why can't they be dealt with in the same way as user interrupt?
The problem is that Haskell does not support getting back to (continue) normal execution flow as there was no exception. So for user interrupt I want to deal with in a way to interrupt execution, cleanup, print to user something, etc. But for other exceptions I want to behave as nothing happened. This is why those cannot be dealt with the same as user interrupt. On way to "behave as nothing happened" is to mask them (and only them) and the other way is to "eat" (and ignore) them. Probably the first would be better if it would be possible. So the second one is the one I have chosen. The third one, to restore execution flow is sadly not possible in Haskell. Would it be possible to add this feature? To have some function which operates on Exception value and can get you back to where the exception was thrown?
uninterruptible :: IO a -> IO a uninterruptible a = *CENSORED*
That is a very scary function indeed. It just discards all exceptions and re-starts the operation. I definitely do not condone its use.
Yes, this one is extreme. For example, this would be more in the line of above arguments: uninterruptible :: IO a -> IO a uninterruptible a = mask_ $ a `catches` [ Handler (\(e :: AsyncException) -> case e of UserInterrupt -> throw e ; _ -> uninterruptible a), Handler (\(_ :: SomeException) -> uninterruptible a) ] Mitar