
On Thu, Oct 14, 2010 at 8:10 PM, Antoine Latter
On Thu, Oct 14, 2010 at 10:20 AM, Michael Snoyman
wrote: Did you have particular reasons why you thought the resources would not be freed correctly Antoine? I'd love any insight you have on this.
I didn't have a good reason at the time, but your email above crystallized it for me - it's that that the MonadCatchIO package doesn't provide the things I need as primitives. Here's my implementation of allocaBytes:
allocaBytes :: (MonadCatchIO m) => Int -> (Ptr a -> m b) -> m b allocaBytes size = bracket (liftIO $ F.mallocBytes size) (liftIO . F.free)
As you've described above, if someone is using this in ErrorT (or even MaybeT) I can't promise that F.free is ever run:
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 _void $ after a return r)
Because the 'do' runs in 'ErrorT', then nothing promises that the line "_void $ after a" is run.
If there are one or two primitives we can add to MonadCatchIO to make it so bracket and finally can be implemented safely I'm all for it. Maybe the simple thing is to just lift them all into the class, but I'm hoping there is a better way to describe what we want.
I thought a bit about this, and I believe the only extra primitive we need is one of bracket, bracket_ or finally. I also noticed the exception-transformers package[1], which seems to be a good replacement for MonadCatchIO. I contacted the author about adding a MonadBracket typeclass, and he said he'll try to get to it. I'm planning on making that my replacement for MonadCatchIO (assuming it turns out correctly), and if so I'd recommend others do the same. Michael [1] http://hackage.haskell.org/package/exception-transformers-0.2