Copyright | (c) 2021 Xy Ren |
---|---|
License | BSD3 |
Maintainer | xy.r@outlook.com |
Stability | unstable |
Portability | non-portable (GHC only) |
Safe Haskell | None |
Language | Haskell2010 |
This module contains the definition of the Eff
monad. Most of the times, you won't need to use this module
directly; user-facing functionalities are all exported via the Cleff module.
This is an internal module and its API may change even between minor versions. Therefore you should be extra careful if you're to depend on this module.
Synopsis
- newtype InternalHandler e = InternalHandler {
- runHandler :: forall es. e (Eff es) ~> Eff es
- newtype Eff es a = Eff {}
- data Env (es :: [Effect])
- data HandlerPtr (e :: Effect)
- emptyEnv :: Env '[]
- adjustEnv :: forall es' es. (Rec HandlerPtr es -> Rec HandlerPtr es') -> Env es -> Env es'
- allocaEnv :: forall e es. Env es -> (# HandlerPtr e, Env es #)
- readEnv :: forall e es. Elem e es => Env es -> InternalHandler e
- writeEnv :: forall e es. HandlerPtr e -> InternalHandler e -> Env es -> Env es
- replaceEnv :: forall e es. Elem e es => HandlerPtr e -> InternalHandler e -> Env es -> Env es
- appendEnv :: forall e es. HandlerPtr e -> InternalHandler e -> Env es -> Env (e ': es)
- updateEnv :: forall es es'. Env es' -> Env es -> Env es
- class KnownList (es :: [k])
- class KnownList es => Subset (es :: [k]) (es' :: [k])
- send :: e :> es => e (Eff es) ~> Eff es
- sendVia :: e :> es' => (Eff es ~> Eff es') -> e (Eff es) ~> Eff es'
The Eff
monad
newtype InternalHandler e Source #
The internal representation of effect handlers. This is just a natural transformation from the effect type
e (
to the effect monad Eff
es)
for any effect stack Eff
eses
.
In interpreting functions (see Cleff.Internal.Interpret), the user-facing Handler
type is transformed into
this type.
InternalHandler | |
|
Instances
Typeable e => Show (InternalHandler e) Source # |
|
Defined in Cleff.Internal.Monad showsPrec :: Int -> InternalHandler e -> ShowS # show :: InternalHandler e -> String # showList :: [InternalHandler e] -> ShowS # |
The extensible effect monad. A monad
is capable of performing any effect in the effect stack Eff
eses
,
which is a type-level list that holds all effects available. However, most of the times, for flexibility, es
should be a polymorphic type variable, and you should use the (:>)
and (:>>)
operators in constraints to
indicate what effects are in the stack. For example,
Reader
String
:>
es,State
Bool
:>
es =>Eff
esInteger
allows you to perform operations of the
effect and the Reader
String
effect in a computation returning an State
Bool
Integer
.
Eff | The effect monad receives an effect environment |
Instances
IOE :> es => MonadBase IO (Eff es) Source # | Compatibility instance; use |
Defined in Cleff.Internal.Base | |
IOE :> es => MonadBaseControl IO (Eff es) Source # | Compatibility instance; use |
Monad (Eff es) Source # | |
Functor (Eff es) Source # | |
MonadFix (Eff es) Source # | |
Defined in Cleff.Internal.Monad | |
Fail :> es => MonadFail (Eff es) Source # | |
Defined in Cleff.Fail | |
Applicative (Eff es) Source # | |
IOE :> es => MonadIO (Eff es) Source # | |
Defined in Cleff.Internal.Base | |
IOE :> es => MonadThrow (Eff es) Source # | |
Defined in Cleff.Internal.Base | |
IOE :> es => MonadCatch (Eff es) Source # | |
IOE :> es => MonadMask (Eff es) Source # | |
IOE :> es => PrimMonad (Eff es) Source # | |
IOE :> es => MonadUnliftIO (Eff es) Source # | |
Defined in Cleff.Internal.Base | |
Semigroup a => Semigroup (Eff es a) Source # | |
Monoid a => Monoid (Eff es a) Source # | |
type PrimState (Eff es) Source # | |
Defined in Cleff.Internal.Base | |
type StM (Eff es) a Source # | |
Defined in Cleff.Internal.Base |
Effect environment
data Env (es :: [Effect]) Source #
The effect environment that corresponds effects in the stack to their respective InternalHandler
s. This
structure simulates memory: handlers are retrieved via pointers (HandlerPtr
s), and for each effect in the stack
we can either change what pointer it uses or change the handler the pointer points to. The former is used for global
effect interpretation (reinterpretN
) and the latter for local interpretation (toEffWith
) in order to
retain correct HO semantics. For more details on this see https://github.com/re-xyr/cleff/issues/5.
data HandlerPtr (e :: Effect) Source #
A pointer to InternalHandler
in an Env
.
Instances
Eq (HandlerPtr e) Source # | Pointer equality. |
Defined in Cleff.Internal.Monad (==) :: HandlerPtr e -> HandlerPtr e -> Bool # (/=) :: HandlerPtr e -> HandlerPtr e -> Bool # | |
Ord (HandlerPtr e) Source # | An arbitrary total order on the pointers. |
Defined in Cleff.Internal.Monad compare :: HandlerPtr e -> HandlerPtr e -> Ordering # (<) :: HandlerPtr e -> HandlerPtr e -> Bool # (<=) :: HandlerPtr e -> HandlerPtr e -> Bool # (>) :: HandlerPtr e -> HandlerPtr e -> Bool # (>=) :: HandlerPtr e -> HandlerPtr e -> Bool # max :: HandlerPtr e -> HandlerPtr e -> HandlerPtr e # min :: HandlerPtr e -> HandlerPtr e -> HandlerPtr e # |
adjustEnv :: forall es' es. (Rec HandlerPtr es -> Rec HandlerPtr es') -> Env es -> Env es' Source #
Adjust the effect stack via an function over Rec
.
allocaEnv :: forall e es. Env es -> (# HandlerPtr e, Env es #) Source #
Allocate a new, empty address for a handler. \( O(1) \).
readEnv :: forall e es. Elem e es => Env es -> InternalHandler e Source #
Read the handler a pointer points to. \( O(1) \).
writeEnv :: forall e es. HandlerPtr e -> InternalHandler e -> Env es -> Env es Source #
Overwrite the handler a pointer points to. \( O(1) \).
replaceEnv :: forall e es. Elem e es => HandlerPtr e -> InternalHandler e -> Env es -> Env es Source #
Replace the handler pointer of an effect in the stack. \( O(n) \).
appendEnv :: forall e es. HandlerPtr e -> InternalHandler e -> Env es -> Env (e ': es) Source #
Add a new effect to the stack with its corresponding handler pointer. \( O(n) \).
updateEnv :: forall es es'. Env es' -> Env es -> Env es Source #
Use the state of LHS as a newer version for RHS. \( O(1) \).
Performing effect operations
The list es
list is concrete, i.e. is of the form '[a1, a2, ..., an]
, i.e. is not a type variable.
Instances
KnownList ('[] :: [k]) | |
Defined in Data.Rec.SmallArray | |
KnownList es => KnownList (e ': es :: [k]) | |
Defined in Data.Rec.SmallArray |
class KnownList es => Subset (es :: [k]) (es' :: [k]) #
es
is a subset of es'
.
Instances
Subset ('[] :: [k]) (es :: [k]) | |
Defined in Data.Rec.SmallArray reifyIndices :: [Int] | |
(Subset es es', Elem e es') => Subset (e ': es :: [k]) (es' :: [k]) | |
Defined in Data.Rec.SmallArray reifyIndices :: [Int] |
send :: e :> es => e (Eff es) ~> Eff es Source #
Perform an effect operation, i.e. a value of an effect type e ::
. This requires Effect
e
to be in the
effect stack.