
On Mon, Jun 21, 2010 at 7:04 AM, Neil Brown
Here's my speculation, based on glancing at the libraries involved: I believe the reason for this may be the MonadCatchIO instance for ContT:
=== instance MonadCatchIO m => MonadCatchIO (ContT r m) where m `catch` f = ContT $ \c -> runContT m c `catch` \e -> runContT (f e) c ===
To my eye, that code takes the continuation to run after the block, c (which in your case involves the after-action from bracket_, and then the error), and runs that inside the catch block. This causes a successful completion of bracket_ (first release), followed by the error, which triggers the catch block which then runs the final actions (second release) and rethrows the error. Does that sound possible to anyone else?
Sounds possible to me.
ContT does not play well with control operations from other monads.
Most people would expect, e.g., lift m `catch` lift . f = lift (m
`catch` f), but ContT does not have such an operation.
If you really want explicit continuations and exceptions, you need a
monad written specifically for that.
--
Dave Menendez