Copyright | © Anders Kaseorg 2010 |
---|---|
License | BSD-style |
Maintainer | Anders Kaseorg <andersk@mit.edu> |
Stability | experimental |
Portability | portable |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Control.Monad.Trans.Peel
Description
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
.
liftOp
and liftOp_
enable convenient lifting of two common special
cases of control operation types.
Synopsis
- 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))
- liftOp :: (MonadTransPeel t, Monad m, Monad n, Monad o, Monad (t n)) => ((a -> m (t o b)) -> n (t n c)) -> (a -> t m b) -> t n c
- liftOp_ :: (MonadTransPeel t, Monad m, Monad n, Monad o, Monad (t n)) => (m (t o a) -> n (t n b)) -> t m a -> t n b
Documentation
class MonadTrans t => MonadTransPeel t where Source #
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.
Methods
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
.
Instances
MonadTransPeel MaybeT Source # | |
MonadTransPeel (ExceptT e) Source # | |
MonadTransPeel (IdentityT :: (Type -> Type) -> Type -> Type) Source # | |
MonadTransPeel (ReaderT r) Source # | |
MonadTransPeel (StateT s) Source # | |
MonadTransPeel (StateT s) Source # | |
Monoid w => MonadTransPeel (WriterT w) Source # | |
Monoid w => MonadTransPeel (WriterT w) Source # | |
Monoid w => MonadTransPeel (RWST r w s) Source # | |
Monoid w => MonadTransPeel (RWST r w s) Source # | |
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
classMonadIO
m => MonadPeelIO m where peelIO :: m (m a ->IO
(m a)) instance MonadPeelIOIO
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
liftOp :: (MonadTransPeel t, Monad m, Monad n, Monad o, Monad (t n)) => ((a -> m (t o b)) -> n (t n c)) -> (a -> t m b) -> t n c Source #