Copyright | (c) Ivan Lazar Miljenovic |
---|---|
License | 3-Clause BSD-style |
Maintainer | Ivan.Miljenovic@gmail.com |
Safe Haskell | None |
Language | Haskell2010 |
- class (Applicative m, Monad m) => MonadTower_ m where
- type BaseMonad m :: * -> *
- type MonadTower m = (MonadTower_ m, MonadTower_ (BaseMonad m), BaseMonad (BaseMonad m) ~ BaseMonad m, BaseMonad m ~ BaseMonad (BaseMonad m))
- class (MonadTower m, MonadTower (LowerMonad m), BaseMonad m ~ BaseMonad (LowerMonad m), BaseMonad (LowerMonad m) ~ BaseMonad m, CanAddInternalM m) => MonadLevel_ m where
- type LowerMonad m :: * -> *
- type InnerValue m a :: *
- type WithLower_ m :: (* -> *) -> * -> *
- type AllowOtherValues m :: Bool
- type DefaultAllowConstraints m :: Bool
- wrap :: CanUnwrap m a b => Proxy a -> Unwrapper m a (LowerMonadValue m b) -> m b
- type MonadLevel m = (MonadLevel_ m, (Forall (CanUnwrapSelf m), WithLowerC m))
- type Unwrapper m a t = (forall b. CanUnwrap m a b => m b -> LowerMonadValue m b) -> WithLower m a -> t
- type LowerMonadValue m a = LowerMonad m (InnerValue m a)
- type WithLower m = WithLower_ m m
- class (MonadLevel_ m, CanUnwrap_ m a b) => CanUnwrap m a b
- class (MonadLevel_ m, CanUnwrap m a a) => CanUnwrapSelf m a
- type WithLowerC m = AddConstraint (WithLower_ m) m
- class AddInternalM ai where
- type AddConstraint ai m :: Constraint
- addInternalM :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b) => ai m a -> LowerMonad m b -> LowerMonadValue m b
- type CanAddInternalM m = AddInternalM (WithLower_ m)
- newtype AddIM m a = AddIM {
- addIMFunc :: forall b. CanUnwrap m a b => LowerMonad m b -> LowerMonadValue m b
- class AddInternalM ai => AddInternal ai where
- addInternal :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b) => ai m a -> b -> InnerValue m b
- mapInternal :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b, CanUnwrap m a c) => ai m a -> (b -> c) -> InnerValue m b -> InnerValue m c
- type CanAddInternal m = AddInternal (WithLower_ m)
- data AddI m a = AddI {
- setIFunc :: forall b. CanUnwrap m a b => b -> InnerValue m b
- mapIFunc :: forall b c. (CanUnwrap m a b, CanUnwrap m a c) => (b -> c) -> InnerValue m b -> InnerValue m c
- data AddIdent m a = AddIdent
- class AddInternal ai => GetInternal ai where
- getInternal :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b) => ai m a -> c -> (b -> c) -> InnerValue m b -> c
- type CanGetInternal m = GetInternal (WithLower_ m)
- data AddIG m a = AddIG {
- setIUFunc :: forall b. CanUnwrap m a b => b -> InnerValue m b
- mapIUFunc :: forall b c. (CanUnwrap m a b, CanUnwrap m a c) => (b -> c) -> InnerValue m b -> InnerValue m c
- getIUFunc :: forall b c. CanUnwrap m a b => c -> (b -> c) -> InnerValue m b -> c
- lift :: forall m a. MonadLevel m => LowerMonad m a -> m a
- class (MonadTower m, m ~ BaseMonad m, BaseMonad m ~ m) => IsBaseMonad m
- type HasBaseMonad m = SatisfyConstraint IsBaseMonad m
- liftBase :: HasBaseMonad m => BaseMonad m a -> m a
- type BaseMonadOf b m = (HasBaseMonad m, BaseMonad m ~ b, b ~ BaseMonad m)
- liftIO :: BaseMonadOf IO m => IO a -> m a
- type HasTransformer t m = (SatisfyConstraint (IsTransformer t) m, MonadLevel (TransformedMonad t m), TransformedMonad t m ~ t (LowerMonad (TransformedMonad t m)))
- type TransformedMonad t m = SatMonad (IsTransformer t) m
- liftT :: HasTransformer t m => TransformedMonad t m a -> m a
Monadic stacks
class (Applicative m, Monad m) => MonadTower_ m Source
Monads in a monadic stack.
For monads that are not instances of MonadicLevel_
then it
suffices to say instance MonadTower_ MyMonad
; for levels it is
required to define BaseMonad
(typically recursively).
You should use MonadTower
in any constraints rather than this
class. This includes when writing instances of MonadTower_
for
monadic transformers.
MonadTower_ [] | |
MonadTower_ IO | |
MonadTower_ Maybe | |
MonadTower_ Identity | |
MonadTower_ ((->) r) | |
MonadTower_ (Either e) | |
Monad m => MonadTower_ (WrappedMonad m) | |
MonadTower m => MonadTower_ (MaybeT m) | |
MonadTower m => MonadTower_ (ListT m) | |
MonadTower m => MonadTower_ (IdentityT m) | |
(Monoid w, MonadTower m) => MonadTower_ (WriterT w m) | |
(Monoid w, MonadTower m) => MonadTower_ (WriterT w m) | |
MonadTower m => MonadTower_ (ExceptT e m) | |
MonadTower m => MonadTower_ (StateT s m) | |
MonadTower m => MonadTower_ (StateT s m) | |
MonadTower m => MonadTower_ (ReaderT r m) | |
MonadTower m => MonadTower_ (ContT r m) | |
(Monoid w, MonadTower m) => MonadTower_ (RWST r w s m) | |
(Monoid w, MonadTower m) => MonadTower_ (RWST r w s m) |
type MonadTower m = (MonadTower_ m, MonadTower_ (BaseMonad m), BaseMonad (BaseMonad m) ~ BaseMonad m, BaseMonad m ~ BaseMonad (BaseMonad m)) Source
This is MonadTower_
with additional sanity constraints to
ensure that applying BaseMonad
is idempotent.
class (MonadTower m, MonadTower (LowerMonad m), BaseMonad m ~ BaseMonad (LowerMonad m), BaseMonad (LowerMonad m) ~ BaseMonad m, CanAddInternalM m) => MonadLevel_ m where Source
How to handle wrappers around existing MonadTower
instances.
For newtype wrappers (e.g. IdentityT
), it is sufficient to only
define LowerMonad
.
You should use MonadLevel
rather than this class in
constraints.
Nothing
type LowerMonad m :: * -> * Source
type InnerValue m a :: * Source
How the value is represented internally; defaults to a
.
type WithLower_ m :: (* -> *) -> * -> * Source
An instance of AddInternalM
; this is defined so as to be able
to make it easier to add constraints rather than solely relying
upon its value within Unwrapper
.
type AllowOtherValues m :: Bool Source
Within the continuation for wrap
for m a
, we can unwrap any
m b
if AllowOtherValues m ~ True
; otherwise, we can only
unwrap m a
. Defaults to True
.
type DefaultAllowConstraints m :: Bool Source
By default, should all constraints be allowed through this
level? Defaults to True
.
wrap :: CanUnwrap m a b => Proxy a -> Unwrapper m a (LowerMonadValue m b) -> m b Source
A continuation-based approach to create a value of this level.
A default is provided for newtype wrappers around existing
MonadTower
instances, provided that - with the exception of
LowerMonad
- all associated types are left as their defaults.
MonadTower m => MonadLevel_ (MaybeT m) | |
MonadTower m => MonadLevel_ (ListT m) | |
MonadTower m => MonadLevel_ (IdentityT m) | |
(Monoid w, MonadTower m) => MonadLevel_ (WriterT w m) | |
(Monoid w, MonadTower m) => MonadLevel_ (WriterT w m) | |
MonadTower m => MonadLevel_ (ExceptT e m) | |
MonadTower m => MonadLevel_ (StateT s m) | |
MonadTower m => MonadLevel_ (StateT s m) | |
MonadTower m => MonadLevel_ (ReaderT r m) | |
MonadTower m => MonadLevel_ (ContT r m) | |
MonadLevel_ m => Class (MonadLevel_ m, CanUnwrap m a a) (CanUnwrapSelf m a) | |
(Monoid w, MonadTower m) => MonadLevel_ (RWST r w s m) | |
(Monoid w, MonadTower m) => MonadLevel_ (RWST r w s m) |
type MonadLevel m = (MonadLevel_ m, (Forall (CanUnwrapSelf m), WithLowerC m)) Source
This is MonadLevel_
with some additional sanity constraints.
Helper types/aliases
type Unwrapper m a t = (forall b. CanUnwrap m a b => m b -> LowerMonadValue m b) -> WithLower m a -> t Source
A continuation function to produce a value of type t
.
type LowerMonadValue m a = LowerMonad m (InnerValue m a) Source
The value contained within the actual level (e.g. for
, this is equivalent to StateT
s m am (a,s)
).
type WithLower m = WithLower_ m m Source
class (MonadLevel_ m, CanUnwrap_ m a b) => CanUnwrap m a b Source
If we're dealing overall with m a
, then this allows us to
specify those b
values for which we can also manipulate m b
.
If
then we require that AllowOtherValues
m ~ Falsea ~ b
;
otherwise, any b
is accepted.
(MonadLevel_ m, CanUnwrap_ m a b) => CanUnwrap m a b | |
MonadLevel_ m => Class (MonadLevel_ m, CanUnwrap m a a) (CanUnwrapSelf m a) |
class (MonadLevel_ m, CanUnwrap m a a) => CanUnwrapSelf m a Source
Used to ensure that for all monad levels, CanUnwrap m a a
is
satisfied.
(MonadLevel_ m, CanUnwrap m a a) => CanUnwrapSelf m a | |
MonadLevel_ m => Class (MonadLevel_ m, CanUnwrap m a a) (CanUnwrapSelf m a) |
type WithLowerC m = AddConstraint (WithLower_ m) m Source
Manipulating internal values
class AddInternalM ai where Source
type AddConstraint ai m :: Constraint Source
addInternalM :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b) => ai m a -> LowerMonad m b -> LowerMonadValue m b Source
type CanAddInternalM m = AddInternalM (WithLower_ m) Source
Used for monad transformers like ContT
where it is not possible
to manipulate the internal value without considering the monad
that it is within.
AddIM | |
|
AddInternalM AddIM | |
type AddConstraint AddIM m = () |
class AddInternalM ai => AddInternal ai where Source
addInternal :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b) => ai m a -> b -> InnerValue m b Source
mapInternal :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b, CanUnwrap m a c) => ai m a -> (b -> c) -> InnerValue m b -> InnerValue m c Source
type CanAddInternal m = AddInternal (WithLower_ m) Source
In most cases you will want to use AddIG
instead of this; this
is defined for cases like ListT
where it may not be possible to
obtain either zero or one value for use with getInternal
.
AddI | |
|
AddInternal AddI | |
AddInternalM AddI | |
type AddConstraint AddI m = () |
Used for monad transformers where
.InnerValue
m a ~ a
class AddInternal ai => GetInternal ai where Source
getInternal :: (MonadLevel m, WithLower_ m ~ ai, CanUnwrap m a b) => ai m a -> c -> (b -> c) -> InnerValue m b -> c Source
This is like a lifted maybe
function that applies to
InnerValue
values rather than just Maybe
s.
type CanGetInternal m = GetInternal (WithLower_ m) Source
Used for monad transformers where it is possible to consider the
InnerValue
in isolation. If InnerValue m a ~ a
then use
AddIdent
instead.
AddIG | |
|
GetInternal AddIG | |
AddInternal AddIG | |
AddInternalM AddIG | |
type AddConstraint AddIG m = () |
Basic level manipulation
lift :: forall m a. MonadLevel m => LowerMonad m a -> m a Source
Lifting from the base
class (MonadTower m, m ~ BaseMonad m, BaseMonad m ~ m) => IsBaseMonad m Source
ValidConstraint IsBaseMonad | |
(MonadTower m, (~) (* -> *) m (BaseMonad m), (~) (* -> *) (BaseMonad m) m) => IsBaseMonad m | |
MonadLevel m => ConstraintPassThrough IsBaseMonad m True | |
type ConstraintSatisfied IsBaseMonad m |
type HasBaseMonad m = SatisfyConstraint IsBaseMonad m Source
Ideally, this alias would not be needed as every instance of
MonadTower
should satisfy the required constraint. However,
this is needed for technical reasons.
liftBase :: HasBaseMonad m => BaseMonad m a -> m a Source
type BaseMonadOf b m = (HasBaseMonad m, BaseMonad m ~ b, b ~ BaseMonad m) Source
liftIO :: BaseMonadOf IO m => IO a -> m a Source
An alias defined for convenience with existing code.
Lifting from a specific transformer
type HasTransformer t m = (SatisfyConstraint (IsTransformer t) m, MonadLevel (TransformedMonad t m), TransformedMonad t m ~ t (LowerMonad (TransformedMonad t m))) Source
Unlike HasBaseMonad
, this is not a universal constraint
applicable to all MonadLevel
instances, as otherwise it can be
used to bypass the lack of an allowed constraint.
type TransformedMonad t m = SatMonad (IsTransformer t) m Source
The sub-part of the monadic stack where the requested transformer is on top.
liftT :: HasTransformer t m => TransformedMonad t m a -> m a Source