On Wed, 14 Apr 2010, Anders Kaseorg wrote:
class Monad m => MonadMorphIO m where morphIO :: (forall b. (m a -> IO b) -> IO b) -> m a
I’d like to experimentally publish this on Hackage. Here are some questions, at least a few of which should ideally have answers before I do so: • Any ideas for what it should be named? I have to admit that I picked “morph” as a relatively generic word that doesn’t really mean anything. I wanted to call it “wrap” but discovered that MonadWrap had been taken by the monad-wrap package, which actually has a very similar goal but is slightly less general (it doesn’t support ContT). • How should the package be split up? If the same class to be useful with both mtl and transformers, one way would be to put class MonadMorphIO and its IO instance, class MonadTransMorph, and whatever useful functions like catch are wrapped with it into one package, then have two additional packages with instances for mtl and transformers, respectively. • What useful functions should be wrapped with it? Some candidates are catch, block, unblock (and friends from Control.Exception), forkIO, runInBoundThread, runInUnboundThread, unsafeInterleaveIO, withProgName, withArgs, alloca (and friends from Foreign.Marshal), withMVar, modifyMVar_, modifyMVar. Then of course there are all the functions that could be wrapped with liftIO… • Can a class like this be expressed in Haskell ’98? (But this seems to be quite difficult, and I imagine we’ll be thinking about it for a while.) • How should this relate to MonadIO? Should MonadMorphIO eventually replace MonadIO entirely? For that matter, should MonadTransMorph replace MonadTrans? • Maybe I’m thinking way too far ahead, and I should just release it now and watch from a safe distance to see what happens? Anders