interruptible- Monad transformers that can be run and resumed later, conserving their context.

Safe HaskellSafe



The problem:

In Haskell it is usually simple to keep IOError bounded within a context, so that they can not interfere with the overall execution of a program. Since functional substitution is done in a hierarchical way, often a single try or catch statement is enough to treat all errors on an entire section of code.

Interruptible monad transformers turn this realitty upside down. Since the entire point of this type class is separating the hierarchical code organization from the monadic contexts, it becomes usefull to keep the exceptions information at the monadic context, instead of the default of carrying it in the code hierarchy.

That is, in the following example:

    let ct1 = createContext 1
        ct2 = createContext 2
    ct1' <- resume startClient ct1
    ct2' <- resume startClient ct2
    resume finishClient ct1'
    resume finishClient ct2'

It may be desirable to let any IO exception on startClient with the ct1 context influence only the execution of finishClient with the ct1' context, and not affect any execution with the other contexts.

SafeIO was created to enforce this kind of behavior.

How to use:

  1. Idealy, do not import lift, liftIO, or anything similar at your module.
  2. Create an error type (let's call it e), and make it an instance of IOErrorDerivation.
  3. Wrap your computation inside an EitherT e transformer (and keep the EitherT the top-level transformer).
  4. Use the safe functions on this module instead of lift, liftIO, liftBase, etc.

Remember that the context of interruptible transformers are in the inverse order that the transformers appear on the stack, thus, at the end of execution if you want to retrieve the EitherT context, you'll have to peel all the other contexts from it first.



class IOErrorDerivation e where Source #

Class for types that keep IOError information. Instantiate this for an error type for using the safe functions from this module.

Minimal complete definition



coerceIOError :: IOError -> e Source #

Transforms an IOError on another error type

safeIO :: (MonadIO m, IOErrorDerivation e) => IO a -> EitherT e m a Source #

Safe alternative to liftIO

safeCT :: (MonadBaseControl IO m, IOErrorDerivation e) => m a -> EitherT e m a Source #

Safe alternative to lift for an stack that implements MonadBaseControl.