| Safe Haskell | None |
|---|
Control.Monad.Layer
Contents
Description
This module is the core of the layers package. It exports:
- The type classes
MonadLayer,MonadLayerFunctorandMonadLayerControland instances of these classes for the transformers in thetransformerspackage. - The type classes
MonadTrans,MonadTransFunctorandMonadTransControland instances of these classes for the transformers in thetransformerspackage. - The type classes
MonadLift,MonadLiftFunctorandMonadLiftControl. - Two sets of helper functions inspired by similarly named functions in
the
monad-controlpackage: one for instances ofMonadLayerControland the other for instances ofMonadLiftControl. These operations are:controlLayer,layerOp,layerOp_andlayerDiscardandcontrol,liftOp,liftOp_andliftDiscardrespectively.
- class (Monad m, Monad (Inner m)) => MonadLayer m where
- class MonadLayer m => MonadLayerFunctor m where
- class MonadLayerFunctor m => MonadLayerControl m where
- data LayerState m :: * -> *
- zero :: LayerState m a -> Bool
- restore :: LayerState m a -> m a
- layerControl :: ((forall b. m b -> Inner m (LayerState m b)) -> Inner m a) -> m a
- class (MonadLayer m, m ~ Outer m (Inner m)) => MonadTrans m where
- type Outer m :: (* -> *) -> * -> *
- transInvmap :: (MonadTrans n, Outer n ~ Outer m) => (forall b. Inner m b -> Inner n b) -> (forall b. Inner n b -> Inner m b) -> m a -> n a
- class (MonadLayerFunctor m, MonadTrans m) => MonadTransFunctor m where
- class (MonadLayerControl m, MonadTransFunctor m) => MonadTransControl m where
- transControl :: (forall n. (MonadTrans n, Outer n ~ Outer m) => (forall b. n b -> Inner n (LayerState n b)) -> Inner n a) -> m a
- class (Monad i, Monad m) => MonadLift i m where
- lift :: i a -> m a
- liftInvmap :: (forall b. i b -> i b) -> (forall b. i b -> i b) -> m a -> m a
- class MonadLift i m => MonadLiftFunctor i m where
- liftMap :: (forall b. i b -> i b) -> m a -> m a
- class MonadLiftFunctor i m => MonadLiftControl i m where
- liftControl :: ((forall b. m b -> i (m b)) -> i a) -> m a
- controlLayer :: MonadLayerControl m => ((forall b. m b -> Inner m (LayerState m b)) -> Inner m (LayerState m a)) -> m a
- layerOp :: MonadLayerControl m => ((a -> Inner m (LayerState m b)) -> Inner m (LayerState m c)) -> (a -> m b) -> m c
- layerOp_ :: MonadLayerControl m => (Inner m (LayerState m a) -> Inner m (LayerState m b)) -> m a -> m b
- layerDiscard :: MonadLayerControl m => (Inner m () -> Inner m a) -> m () -> m a
- control :: MonadLiftControl i m => ((forall b. m b -> i (m b)) -> i (m a)) -> m a
- liftOp :: MonadLiftControl i m => ((a -> i (m b)) -> i (m c)) -> (a -> m b) -> m c
- liftOp_ :: MonadLiftControl i m => (i (m a) -> i (m b)) -> m a -> m b
- liftDiscard :: MonadLiftControl i m => (i () -> i a) -> m () -> m a
The MonadLayer family
class (Monad m, Monad (Inner m)) => MonadLayer m whereSource
A monad m can be an instance of MonadLayer if it is built
("layered") on top of some inner monad () and can provide the
operations Inner mlayer and layerInvmap.
Monad layers are a generalisation of monad transformers, with the difference being that monad layers are not necessarily parametric in their inner monad. For more details, read the the in-depth documentation provided in Documentation.Layers.Overview.
Methods
layer :: Inner m a -> m aSource
layer takes a computation from the inner monad and
lifts it into the "outer" monad Inner mm.
The following laws hold for valid instances of MonadLayer:
- Identity
-
layer . return = return - Composition
-
layer m >>= layer . f = layer (m >>= f)
These laws are equivalent to the monad transformer laws of the
MonadTrans class from the transformers,
where layer is analgous to the lift
operation from MonadTrans.
Arguments
| :: (forall b. Inner m b -> Inner m b) | f |
| -> (forall b. Inner m b -> Inner m b) | g |
| -> m a | |
| -> m a |
layerInvmap represents an invariant (endo)functor in the category
of monads. It takes a transformation f of the inner monad and its
inverse g (such that g . f = id) and returns transformation of m
analogous to f. (i.e., layerInvmap lifts an automorphism of
to an endomorphism of Inner mm).
The following laws hold for valid instances of MonadLayer:
- Identity
-
layerInvmap id id = id - Composition
-
layerInvmap f g . layerInvmap f' g' = layerInvmap (f . f') (g' . g)
Instances
| Monad m => MonadLayer (MaybeT m) | |
| Monad m => MonadLayer (ListT m) | |
| Monad m => MonadLayer (IdentityT m) | |
| (Monad m, Monoid w) => MonadLayer (WriterT w m) | |
| (Monad m, Monoid w) => MonadLayer (WriterT w m) | |
| Monad m => MonadLayer (StateT s m) | |
| Monad m => MonadLayer (StateT s m) | |
| Monad m => MonadLayer (ReaderT r m) | |
| (Error e, Monad m) => MonadLayer (ErrorT e m) | |
| Monad m => MonadLayer (ContT r m) | |
| (Monad m, Monoid w) => MonadLayer (RWST r w s m) | |
| (Monad m, Monoid w) => MonadLayer (RWST r w s m) |
class MonadLayer m => MonadLayerFunctor m whereSource
The type class MonadLayerFunctor represents is the subclass of
monad layers that support the layerMap operation, which is more powerful
than the layerInvmap operation of the MonadLayer type class.
Methods
layerMap :: (forall b. Inner m b -> Inner m b) -> m a -> m aSource
layerMap represents an (endo)functor in the category of monads. It
takes a transformation f of the inner monad returns a transformation
of m analogous to f. (i.e., layerMap lifts an endomorphism of
to a endomorphism of Inner mm).
The following laws hold for valid instances of MonadLayerFunctor:
- Identity
-
layerMap id = id - Composition
-
layerMap f . layerMap g = layerMap (f . g)
Instances
| Monad m => MonadLayerFunctor (MaybeT m) | |
| Monad m => MonadLayerFunctor (ListT m) | |
| Monad m => MonadLayerFunctor (IdentityT m) | |
| (Monad m, Monoid w) => MonadLayerFunctor (WriterT w m) | |
| (Monad m, Monoid w) => MonadLayerFunctor (WriterT w m) | |
| Monad m => MonadLayerFunctor (StateT s m) | |
| Monad m => MonadLayerFunctor (StateT s m) | |
| Monad m => MonadLayerFunctor (ReaderT r m) | |
| (Error e, Monad m) => MonadLayerFunctor (ErrorT e m) | |
| (Monad m, Monoid w) => MonadLayerFunctor (RWST r w s m) | |
| (Monad m, Monoid w) => MonadLayerFunctor (RWST r w s m) |
class MonadLayerFunctor m => MonadLayerControl m whereSource
MonadLayerControl represents the class of monad layers through which it
is possible to lift control operations. See Documentation.Layers.Overview
for a more complete discussion.
Associated Types
data LayerState m :: * -> *Source
The portion of the monadic state of m that is independent of
.
Inner m
Methods
zero :: LayerState m a -> BoolSource
zero inspects a LayerState value and determines whether or not it
is a "zero" value in the monad m (i.e., if m had short-circuited
when the LayerState was captured). (This is used to implement the
universal pass-through instance of
MonadTry.)
restore :: LayerState m a -> m aSource
Construct a m computation from the monadic state of m that is
returned from a run function given by layerControl.
Instances should satisfy the following law:
- Preservation
-
layerControl (\run -> run t) >>= restore = t
layerControl :: ((forall b. m b -> Inner m (LayerState m b)) -> Inner m a) -> m aSource
layerControl is a version of layer that makes it possible to lift
control operations from the inner monad to the "outer"
monad Inner mm. It takes a continuation, to which it passes an operation we
call run, which is a kind of "inverse" of layer.
Instances should satisfy similar laws as the monad transformer laws:
- Identity
-
layerControl . const . return = return - Composition
-
layerControl (const m) >>= layerControl . const . f=layerControl (const (m >>= f))
Instances
| Monad m => MonadLayerControl (MaybeT m) | |
| Monad m => MonadLayerControl (ListT m) | |
| Monad m => MonadLayerControl (IdentityT m) | |
| (Monad m, Monoid w) => MonadLayerControl (WriterT w m) | |
| (Monad m, Monoid w) => MonadLayerControl (WriterT w m) | |
| Monad m => MonadLayerControl (StateT s m) | |
| Monad m => MonadLayerControl (StateT s m) | |
| Monad m => MonadLayerControl (ReaderT r m) | |
| (Error e, Monad m) => MonadLayerControl (ErrorT e m) | |
| (Monad m, Monoid w) => MonadLayerControl (RWST r w s m) | |
| (Monad m, Monoid w) => MonadLayerControl (RWST r w s m) |
The MonadTrans family
class (MonadLayer m, m ~ Outer m (Inner m)) => MonadTrans m whereSource
Monad transformers are a subclass of monad layers which are parametric in their inner monad.
Associated Types
Methods
transInvmap :: (MonadTrans n, Outer n ~ Outer m) => (forall b. Inner m b -> Inner n b) -> (forall b. Inner n b -> Inner m b) -> m a -> n aSource
transInvmap represents an invariant functor in the category of
monads. It takes a transformation f from the inner monad and its
inverse g (such that g . f = id) and returns transformation of m
analogous to f. (i.e., layerInvmap lifts an isomorphism from
to a homomorphism of Inner mm).
The following laws hold for valid instances of MonadTrans:
- Identity
-
transInvmap id id = id - Composition
-
transInvmap f g . transInvmap f' g' = transInvmap (f . f') (g' . g)
Note: this is more powerful than layerInvmap from the MonadLayer
type class because the transformation it produces is a homomorphism
rather than just an endomorphism.
Instances
| Monad m => MonadTrans (MaybeT m) | |
| Monad m => MonadTrans (ListT m) | |
| Monad m => MonadTrans (IdentityT m) | |
| (Monad m, Monoid w) => MonadTrans (WriterT w m) | |
| (Monad m, Monoid w) => MonadTrans (WriterT w m) | |
| Monad m => MonadTrans (StateT s m) | |
| Monad m => MonadTrans (StateT s m) | |
| Monad m => MonadTrans (ReaderT r m) | |
| (Error e, Monad m) => MonadTrans (ErrorT e m) | |
| Monad m => MonadTrans (ContT r m) | |
| (Monad m, Monoid w) => MonadTrans (RWST r w s m) | |
| (Monad m, Monoid w) => MonadTrans (RWST r w s m) |
class (MonadLayerFunctor m, MonadTrans m) => MonadTransFunctor m whereSource
The type class MonadTransFunctor represents is the subclass of
monad layers that support the transMap operation, which is more powerful
than the transInvmap operation of the MonadTrans type class.
Methods
transMap :: (MonadTrans n, Outer n ~ Outer m) => (forall b. Inner m b -> Inner n b) -> m a -> n aSource
transMap represents a functor in the category of monads. It takes
a transformation f from the inner monad returns a transformation from
m analogous to f. (i.e., transMap lifts a homomorphism from
to a homomorphism from Inner mm).
The following laws hold for valid instances of MonadTransFunctor:
- Identity
-
transMap id = id - Composition
-
transMap f . transMap g = transMap (f . g)
Note: this is more powerful than layerMap from the
MonadLayerFunctor type class because the transformation it produces
is a homomorphism rather than just an endomorphism.
Instances
| Monad m => MonadTransFunctor (MaybeT m) | |
| Monad m => MonadTransFunctor (ListT m) | |
| Monad m => MonadTransFunctor (IdentityT m) | |
| (Monad m, Monoid w) => MonadTransFunctor (WriterT w m) | |
| (Monad m, Monoid w) => MonadTransFunctor (WriterT w m) | |
| Monad m => MonadTransFunctor (StateT s m) | |
| Monad m => MonadTransFunctor (StateT s m) | |
| Monad m => MonadTransFunctor (ReaderT r m) | |
| (Error e, Monad m) => MonadTransFunctor (ErrorT e m) | |
| (Monad m, Monoid w) => MonadTransFunctor (RWST r w s m) | |
| (Monad m, Monoid w) => MonadTransFunctor (RWST r w s m) |
class (MonadLayerControl m, MonadTransFunctor m) => MonadTransControl m whereSource
MonadTransControl is a variant of MonadLayerControl for monad
transformers, i.e., monad layers polymorphic in their inner monad. This
extra polymorphism allows us to specify more type safety in the run
operation of transControl, but in practice there is no reason to ever use
this over MonadLayerControl. See Documentation.Layers.Overview for a
discussion of why this class is included despite not being strictly
necessary.
Methods
transControl :: (forall n. (MonadTrans n, Outer n ~ Outer m) => (forall b. n b -> Inner n (LayerState n b)) -> Inner n a) -> m aSource
transControl is a version of layerControl whose run operation
is more polymorphic in the returned monad. This provides a static
guarantee that there are no remaining side effects in m in the action
returned by run which is not possible to express with the types of
MonadLayerControl. In practice though there should be no reason to
use this over layerControl.
Instances
| Monad m => MonadTransControl (MaybeT m) | |
| Monad m => MonadTransControl (ListT m) | |
| Monad m => MonadTransControl (IdentityT m) | |
| (Monad m, Monoid w) => MonadTransControl (WriterT w m) | |
| (Monad m, Monoid w) => MonadTransControl (WriterT w m) | |
| Monad m => MonadTransControl (StateT s m) | |
| Monad m => MonadTransControl (StateT s m) | |
| Monad m => MonadTransControl (ReaderT r m) | |
| (Error e, Monad m) => MonadTransControl (ErrorT e m) | |
| (Monad m, Monoid w) => MonadTransControl (RWST r w s m) | |
| (Monad m, Monoid w) => MonadTransControl (RWST r w s m) |
The MonadLift family
class (Monad i, Monad m) => MonadLift i m whereSource
MonadLift is a multi-parameter type class parameterised by two monads
i and m. If the constraint MonadLift i m is satisfied, this means
that m supports lifting operations from i. If m is a monad built from
a monad transformer stack, then it supports lifting operations from any
monad i anywhere in the stack. We call such a relationship between i
and m a "monad lift". For a more details, read the in-depth
documentation provided in Documentation.Layers.Overview.
Methods
lift takes a computation from an inner monad i and lifts it into
the "outer" monad m.
The following laws hold for valid instances of MonadLift:
- Identity
-
lift . return = return - Composition
-
lift m >>= lift . f = lift (m >>= f)
These laws are equivalent to the monad transformer laws of the
MonadTrans class from the transformers
package.
liftInvmap :: (forall b. i b -> i b) -> (forall b. i b -> i b) -> m a -> m aSource
liftInvmap represents an invariant (endo)functor in the category
of monads. It takes a transformation f of an inner monad i and its
inverse g (such that g . f = id) and returns transformation of m
analogous to f. (i.e., liftInvmap lifts an automorphism of i
to an endomorphism of m).
The following laws hold for valid instances of MonadLift:
- Identity
-
liftInvmap id id = id - Composition
-
liftInvmap f g . liftInvmap f' g' = liftInvmap (f . f') (g' . g)
The difference between liftInvmap and layerInvmap is that
layerInvmap only lifts from the monad directly beneath the top of the
stack, while liftInvmap can lift from any monad anywhere in the
stack (including m itself). (layerInvmap is used to implement
liftInvmap)
class MonadLift i m => MonadLiftFunctor i m whereSource
The type class MonadLiftFunctor represents is the subclass of monad
lifts that support the liftMap operation, which is more powerful than the
liftInvmap operation of the MonadLift type class.
Methods
liftMap :: (forall b. i b -> i b) -> m a -> m aSource
liftMap represents an (endo)functor in the category of monads. It
takes a transformation f of an inner monad i returns a
transformation of m analogous to f. (i.e., liftInvmap lifts an
endomorphism of i to an endomorphism of m).
The following laws hold for valid instances of MonadLiftFunctor:
- Identity
-
liftMap id = id - Composition
-
liftMap f . liftMap g = liftMap (f . g)
The difference between liftMap and layerMap is that layerMap only
lifts from the monad directly beneath the top of the stack, while
liftMap can lift from any monad anywhere in the stack (including
m itself). (layerMap is used to implement liftMap)
Instances
| (MonadLayerFunctor m, MonadLiftFunctor i (Inner m)) => MonadLiftFunctor i m | |
| Monad m => MonadLiftFunctor m m |
class MonadLiftFunctor i m => MonadLiftControl i m whereSource
MonadLiftControl represents the class of monad lifts that support
lifting control operations. See Documentation.Layers.Overview for a more
complete discussion.
Methods
liftControl :: ((forall b. m b -> i (m b)) -> i a) -> m aSource
liftControl is a version of lift that makes it possible to lift
control operations from an inner monad i to the "outer" monad m.
It takes a continuation, to which it passes an operation we call run,
which is a kind of "inverse" of lift.
Instances should satisfy the following laws:
- Identity
-
liftControl . const . return = return - Composition
-
liftControl (const m) >>= liftControl . const . f=liftControl (const (m >>= f)) - Preservation
-
join (liftControl (\run -> run t)) = t
Instances
| (MonadLayerControl m, MonadLiftControl i (Inner m)) => MonadLiftControl i m | |
| Monad m => MonadLiftControl m m |
Helper functions
MonadLayerControl
These functions are mainly used for writing universal pass-through
instances for monad interfaces. If you are not doing this, you're
probably looking for the analogous functions for MonadLiftControl
(see below).
controlLayer :: MonadLayerControl m => ((forall b. m b -> Inner m (LayerState m b)) -> Inner m (LayerState m a)) -> m aSource
An often used composition: controlLayer f = layerControl f >>= restore
layerOp :: MonadLayerControl m => ((a -> Inner m (LayerState m b)) -> Inner m (LayerState m c)) -> (a -> m b) -> m cSource
layerOp is a particular application of layerControl that allows layering
control operations of type: (a -> to
Inner m b) -> Inner m b.
MonadLayerControl m => (a -> m b) -> m b
For example:
layerOp . withMVar :: (MonadLayerControlm,Innerm ~IO) => MVar a -> (a -> m b) -> m b
layerOp_ :: MonadLayerControl m => (Inner m (LayerState m a) -> Inner m (LayerState m b)) -> m a -> m bSource
layerOp_ is a particular application of layerControl that allows
layering control operations of type: to
Inner m a -> Inner m b.
MonadLayerControl m => m a -> m b
For example:
layerOp_ mask_ :: (MonadLayerControlm,Innerm ~IO) => m a -> m a
layerDiscard :: MonadLayerControl m => (Inner m () -> Inner m a) -> m () -> m aSource
layerDiscard is a particular application of layerControl that allows
layering control operations of type: to
Inner m () -> Inner m a.
MonadLayerControl m => m () -> m a
Note that, while the argument computation m () has access to the captured
state, all its side-effects in m are discarded. It is run only for its
side-effects in the inner monad .
Inner m
For example:
layerDiscard forkIO :: (MonadLayerControlm,Innerm ~IO) => m () -> m ThreadId
MonadLiftControl
control :: MonadLiftControl i m => ((forall b. m b -> i (m b)) -> i (m a)) -> m aSource
An often used composition: control f = join . liftControl f
liftOp :: MonadLiftControl i m => ((a -> i (m b)) -> i (m c)) -> (a -> m b) -> m cSource
liftOp is a particular application of liftControl that allows lifting
control operations of type: (a -> i b) -> i b to
.
MonadLiftControl i m => (a -> m b) -> m b
For example:
liftOp . withMVar ::MonadLiftControlIOm => MVar a -> (a -> m b) -> m b
liftOp_ :: MonadLiftControl i m => (i (m a) -> i (m b)) -> m a -> m bSource
liftOp_ is a particular application of liftControl that allows
lifting control operations of type: i a -> i b to
.
MonadLiftControl i m => m a -> m b
For example:
liftOp_ mask_ ::MonadLiftControlIOm => m a -> m a
liftDiscard :: MonadLiftControl i m => (i () -> i a) -> m () -> m aSource
liftDiscard is a particular application of liftControl that allows
lifting control operations of type: i () -> i a to
.
MonadLiftControl i m => m () -> m a
Note that, while the argument computation m () has access to the captured
state, all its side-effects in m are discarded. It is run only for its
side-effects in the inner monad i.
For example:
liftDiscard forkIO ::MonadLiftControlIOm => m () -> m ThreadId