Haskell monad-peel library

Lift control operations like exception catching through monad transformers

This package defines MonadPeelIO, a subset of MonadIO into which generic control operations such as catch can be lifted from IO. Instances are based on monad transformers in MonadTransPeel, which includes all standard monad transformers in the transformers library except ContT. For convenience, it provides a wrapped version of Control.Exception with types generalized from IO to all monads in MonadPeelIO.

Package

Background/History

generic catch in a MonadIO, haskell list, 2006-02-07
Oleg Kiselyov introduces CaughtMonadIO with a gcatch method generalizing catch. Ashley Yakeley suggests class StrictMonadIO containing getUnliftIO, which is powerful enough to construct gcatch, but does not present an implementation.
Generalize types of IO actions, Haskell Prime Trac, 2006-04-21;
Control.Exceptions and MonadIO, haskell-cafe list, 2006-04-22
Brian Hulley points out that StrictMonadIO cannot be correctly implemented for stateful monad transformers, and proposes class MonadException containing catch, block, unblock, and setUncaughtExceptionHandler.
Monadic tunnelling: the art of threading one monad through another, haskell-cafe list, 2007-07-11
Jules Bean introduces class InterleavableIO which threads monadic state through IO using IORefs.
MonadCatchIO-mtl library, Hackage, 2008-12-31
Daniel Gorín releases class MonadCatchIO with catch, block, and unblock (similar to Hulley’s MonadException).
monad-wrap library, Hackage, 2009-10-17
David Mazieres releases class MonadWrap with wrap and resultF, using MPTC+FDs; it seems to allow a limited kind of monadic catching where the handler runs in IO.
MonadMorphIO [Re: Move MonadIO to base], libraries list, 2010-04-14
I introduce class MonadMorphIO, which uses rank-2 types and is powerful enough to construct a fully-general catch. I implement it for all monads in MTL, though David Menendez points out that instance for ContT is wrong. Wren Ng Thornton attempts to exhibit an isomorphism with a simpler class MonadJoinIO that is Haskell 98, but it doesn’t quite work for ReaderT.
MonadCatchIO, finally and the error monad, haskell-cafe list, 2010-10-14
Michael Snoyman discovers that the finally implementation in MonadCatchIO is broken in monads with short-circuiting control flow, showing that a general finally needs to be derived from the finally in IO and not just from a general catch.
Invertible monads for exception handling and memory allocations, Yesod Blog, 2010-10-15
Michael Snoyman creates class MonadInvertIO with invertIO and revertIO, using type families; this is powerful enough to generalize everything in Control.Exception including catch and finally. I reply with a way to combine this idea with MonadMorphIO to get a solution that uses only rank-2 types, but is not quite powerful enough to generalize bracket. Thinking through this problem and combining several of the ideas above eventually led to MonadPeelIO.
Generalized monadic exception handling with monad-peel, haskell-cafe list, 2010-11-03
My announcement of monad-peel.