Safe Haskell | None |
---|
This module is the core of the layers
package. It exports:
- The type classes
MonadLayer
,MonadLayerFunctor
andMonadLayerControl
and instances of these classes for the transformers in thetransformers
package. - The type classes
MonadTrans
,MonadTransFunctor
andMonadTransControl
and instances of these classes for the transformers in thetransformers
package. - The type classes
MonadLift
,MonadLiftFunctor
andMonadLiftControl
. - Two sets of helper functions inspired by similarly named functions in
the
monad-control
package: one for instances ofMonadLayerControl
and the other for instances ofMonadLiftControl
. These operations are:controlLayer
,layerOp
,layerOp_
andlayerDiscard
andcontrol
,liftOp
,liftOp_
andliftDiscard
respectively.
- 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.
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
.
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)
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.
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)
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.
data LayerState m :: * -> *Source
The portion of the monadic state of m
that is independent of
.
Inner
m
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))
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.
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.
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.
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.
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.
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
.
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.
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.
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
)
(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.
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
(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 :: (MonadLayerControl
m,Inner
m ~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_ :: (MonadLayerControl
m,Inner
m ~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 :: (MonadLayerControl
m,Inner
m ~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 ::MonadLiftControl
IO
m => 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_ ::MonadLiftControl
IO
m => 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 ::MonadLiftControl
IO
m => m () -> m ThreadId