[Haskell-cafe] MonadCatchIO and bracket.

Michael Snoyman 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[1] 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.


[1] http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/76262
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100628/6ade2435/attachment.html

More information about the Haskell-Cafe mailing list