
I wrote:
unfortunately, bracket is currently not available for MonadIO, nor is there any way to emulate it AFIK. (This is a "maybe" for HaskellPrime: http://hackage.haskell.org/trac/haskell-prime/ticket/110)
Judah Jacobson wrote:
Following is what I've been using to solve that problem. I can add it to that HaskellPrime ticket if people think it's useful.
Very nice! I think you should not only add it to the ticket (if that is still relevant, I am not sure what is going on with Haskell' right now), but you should also submit a patch for the mtl library. We need a better name than IO1, though.
Note that in bracket1, the "after" action must run in IO. In practice, that hasn't been a problem for me. In fact, since the "after" clause might run in response to an asynchronous exception, I don't see how it could be sequenced with an arbitrary monad, anyway.
Agreed. The real fix would be to provide a lower-level primitive for block and unblock. The concurrency paper "Asynchronous exceptions in Haskell" states (sec. 4.2) that the reason for the type block :: IO a -> IO a rather than the more obvious block :: IO () is clumsiness and fragility. That may be so. But that type is too high-level for a primitive. In GHC, the implementation of block is: block (IO io) = IO $ blockAsyncExceptions# io It should really be: block x = do IO blockAsyncExceptions# ret <- x IO unblockAsyncExceptions# return ret in which case we could then supply implementations for other monads as well. Regards, Yitz