
Yitzchak Gale wrote:
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.
blockAsyncExceptions# has some tricks to restore tail-recursion in some cases (see the paper). But apart from losing that optimisation, I can't think of any reasons why the above couldn't work - one thing you have to worry about is what happens when x raises an exeption, but I think that is handled by the way we save and restore the blocked state in catch. Cheers, Simon