[Haskell-cafe] MonadCatchIO and bracket.
michael at snoyman.com
Mon Jun 28 16:09:47 EDT 2010
On Mon, Jun 28, 2010 at 10:02 PM, Carl Howells <chowells79 at gmail.com> wrote:
> While working this weekend on the Snap web framework, I ran into a
> problem. Snap implements MonadCatchIO, so I thought I could just use
> bracket to handle resource acquisition/release in a safe manner.
> Imagine my surprise when bracket simply failed to run the release
> action sometimes.
> I quickly determined the times when it doesn't run are when Snap's
> monadic short-circuiting is used. I dug into the source of bracket
> (in the transformers branch, though the mtl branch has the same
> behavior in these cases, with slightly different code), and the reason
> why quickly became obvious:
> -- | Generalized version of 'E.bracket'
> bracket :: MonadCatchIO m => m a -> (a -> m b) -> (a -> m c) -> m c
> bracket before after thing = block $ do
> a <- before
> r <- unblock (thing a) `onException` after a
> _ <- after a
> return r
> When monadic short-circuiting applies, the "_ <- after a" line gets
> completely ignored. In discussions with #haskell on this topic, it
> quickly became clear that for any monad transformer that can affect
> control flow, the definition of bracket in MonadCatchIO doesn't keep
> the guarantee provided by bracket in Control.Exception, which is that
> the "after" action will be run exactly once.
> Because of that, I think bracket needs to be a class function.
> Furthermore, I think it needs to be a new class, ie
> class MonadCatchIO m => MonadBracketIO m where
> bracket :: m a -> (a -> m b) -> (a -> m c) -> m c
> This would allow its definition in cases where it makes sense (Snap or
> MaybeT IO), but it could be left out in cases where it doesn't make
> sense, like ListT IO, even though MonadCatchIO makes sense there.
> I'm not sure if it's related to this, but I had a problem using the
ContT instance of MonadCatchIO, but there the result was the opposite: I
would have resources released twice. I would really like to have that one
solved as well.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe