
wren ng thornton wrote:
Anders Kaseorg wrote:
On Tue, 13 Apr 2010, Anders Kaseorg wrote:
The striking similarity between instances of MonadCatchIO suggests to me that something deeper is going on. Is there a cleaner abstraction that captures this idea?
Here a possible answer. I haven’t entirely figured out what it “means” yet, but maybe someone who knows more category theory will be able to figure that out. :-)
class Monad m => MonadMorphIO m where morphIO :: (forall b. (m a -> IO b) -> IO b) -> m a
[...] Putting these together, your class means: if you can construct/eliminate an (F m a) in the IO category, then you can construct an (m a) in the Hask category. I.e., IO(m a) is a subset of (m a).
Which is more general than liftIO which only says (IO a) is a subset of (m a). That is, liftIO requires that the non-IO layers of m are constructed via `return`, whereas morphIO permits non-pointed use of IO. In other words, liftIO only allows lifting "effectful" values, whereas morphIO also allows lifting "structural" values. -- Live well, ~wren