Portability | portable |
---|---|

Stability | experimental |

Maintainer | Anders Kaseorg <andersk@mit.edu> |

This module defines the class `MonadTransPeel`

of monad transformers
through which control operations can be lifted. Instances are
included for all the standard monad transformers from the
`transformers`

library except `ContT`

.

`idPeel`

and `liftPeel`

are provided to assist creation of
`MonadPeelIO`

-like classes (see Control.Monad.IO.Peel) based on core
monads other than `IO`

.

- class MonadTrans t => MonadTransPeel t where
- idPeel :: (Monad m, Monad n, Monad o) => n (m a -> m (o a))
- liftPeel :: (MonadTransPeel t, Monad m, Monad m', Monad n', Monad (t n'), Monad o', Monad (t o')) => n' (m' (t o' a) -> m (o' (t o' a))) -> t n' (t m' a -> m (t o' a))

# Documentation

class MonadTrans t => MonadTransPeel t whereSource

`MonadTransPeel`

is the class of monad transformers supporting an
extra operation `peel`

, enabling control operations (functions that
use monadic actions as input instead of just output) to be lifted
through the transformer.

peel :: (Monad m, Monad n, Monad o) => t n (t m a -> m (t o a))Source

`peel`

is used to peel off the outer layer of a transformed
monadic action, allowing an transformed action `t m a`

to be
treated as a base action `m b`

.

More precisely, `peel`

captures the monadic state of `t`

at the
point where it is bound (in `t n`

), yielding a function ```
t m a ->
m (t o a)
```

; this function runs a transformed monadic action ```
t m
a
```

in the base monad `m`

using the captured state, and leaves the
result `t o a`

in the monad `m`

after all side effects in `m`

have occurred.

This can be used together with `lift`

to lift control operations
with types such as `M a -> M a`

into the transformed monad `t M`

:

instance Monad M foo :: M a -> M a foo' :: (`MonadTransPeel`

t,`Monad`

(t M)) => t M a -> t M a foo' a = do k <-`peel`

-- k :: t M a -> M (t M a)`join`

$`lift`

$ foo (k a) -- uses foo :: M (t M a) -> M (t M a)

`peel`

is typically used with `m == n == o`

, but is required to
be polymorphic for greater type safety: for example, this type
ensures that the result of running the action in `m`

has no
remaining side effects in `m`

.

MonadTransPeel MaybeT | |

MonadTransPeel ListT | |

MonadTransPeel IdentityT | |

Monoid w => MonadTransPeel (WriterT w) | |

Monoid w => MonadTransPeel (WriterT w) | |

MonadTransPeel (StateT s) | |

MonadTransPeel (StateT s) | |

MonadTransPeel (ReaderT r) | |

Error e => MonadTransPeel (ErrorT e) | |

Monoid w => MonadTransPeel (RWST r w s) | |

Monoid w => MonadTransPeel (RWST r w s) |

idPeel :: (Monad m, Monad n, Monad o) => n (m a -> m (o a))Source

`idPeel`

acts as the "identity" `peel`

operation from a monad
`m`

to itself.

`idPeel`

=`return`

$`liftM`

`return`

It serves as the base case for a class like `MonadPeelIO`

, which
allows control operations in some base monad (here `IO`

) to be
lifted through arbitrary stacks of zero or more monad transformers
in one call. For example, Control.Monad.IO.Peel defines

class`MonadIO`

m => MonadPeelIO m where peelIO :: m (m a ->`IO`

(m a)) instance MonadPeelIO`IO`

where peelIO =`idPeel`

liftPeel :: (MonadTransPeel t, Monad m, Monad m', Monad n', Monad (t n'), Monad o', Monad (t o')) => n' (m' (t o' a) -> m (o' (t o' a))) -> t n' (t m' a -> m (t o' a))Source

`liftPeel`

is used to compose two `peel`

operations: the outer
provided by a `MonadTransPeel`

instance, and the inner provided as
the argument.

It satisfies

.
`liftPeel`

`idPeel`

== `peel`

It serves as the induction step of a `MonadPeelIO`

-like class. For
example, Control.Monad.IO.Peel defines

instance MonadPeelIO m => MonadPeelIO (`StateT`

s m) where peelIO =`liftPeel`

peelIO

using the `MonadTransPeel`

instance of

.
`StateT`

s