Copyright | (c) Fumiaki Kinoshita 2018 |
---|---|
License | BSD3 |
Maintainer | Fumiaki Kinoshita <fumiexcel@gmail.com> |
Safe Haskell | None |
Language | Haskell2010 |
Name-based extensible effects
Synopsis
- data Instruction (xs :: [Assoc k (Type -> Type)]) a where
- Instruction :: !(Membership xs kv) -> TargetOf kv a -> Instruction xs a
- type Eff xs = Skeleton (Instruction xs)
- liftEff :: forall s t xs a. Lookup xs s t => Proxy s -> t a -> Eff xs a
- liftsEff :: forall s t xs a r. Lookup xs s t => Proxy s -> t a -> (a -> r) -> Eff xs r
- hoistEff :: forall s t xs a. Lookup xs s t => Proxy s -> (forall x. t x -> t x) -> Eff xs a -> Eff xs a
- castEff :: IncludeAssoc ys xs => Eff xs a -> Eff ys a
- newtype Interpreter f g = Interpreter {
- runInterpreter :: forall a. g a -> f a
- handleEff :: RecordOf (Interpreter m) xs -> Eff xs a -> MonadView m (Eff xs) a
- peelEff :: forall k t xs a r. Rebinder xs r -> (a -> r) -> (forall x. t x -> (x -> r) -> r) -> Eff ((k >: t) ': xs) a -> r
- type Rebinder xs r = forall x. Instruction xs x -> (x -> r) -> r
- rebindEff0 :: Rebinder xs (Eff xs r)
- peelEff0 :: forall k t xs a r. (a -> Eff xs r) -> (forall x. t x -> (x -> Eff xs r) -> Eff xs r) -> Eff ((k >: t) ': xs) a -> Eff xs r
- rebindEff1 :: Rebinder xs (a -> Eff xs r)
- peelEff1 :: forall k t xs a b r. (a -> b -> Eff xs r) -> (forall x. t x -> (x -> b -> Eff xs r) -> b -> Eff xs r) -> Eff ((k >: t) ': xs) a -> b -> Eff xs r
- rebindEff2 :: Rebinder xs (a -> b -> Eff xs r)
- leaveEff :: Eff '[] a -> a
- retractEff :: forall k m a. Monad m => Eff '[k >: m] a -> m a
- data Action (args :: [Type]) a r where
- type family Function args r :: Type where ...
- runAction :: Function xs (f a) -> Action xs a r -> f r
- (@!?) :: FieldName k -> Function xs (f a) -> Field (Interpreter f) (k :> Action xs a)
- peelAction :: forall k ps q xs a r. (forall x. Instruction xs x -> (x -> r) -> r) -> (a -> r) -> Function ps ((q -> r) -> r) -> Eff ((k >: Action ps q) ': xs) a -> r
- peelAction0 :: forall k ps q xs a. Function ps (Eff xs q) -> Eff ((k >: Action ps q) ': xs) a -> Eff xs a
- type ReaderEff = (:~:)
- askEff :: forall k r xs. Lookup xs k (ReaderEff r) => Proxy k -> Eff xs r
- asksEff :: forall k r xs a. Lookup xs k (ReaderEff r) => Proxy k -> (r -> a) -> Eff xs a
- localEff :: forall k r xs a. Lookup xs k (ReaderEff r) => Proxy k -> (r -> r) -> Eff xs a -> Eff xs a
- runReaderEff :: forall k r xs a. Eff ((k >: ReaderEff r) ': xs) a -> r -> Eff xs a
- type State s = StateT s Identity
- getEff :: forall k s xs. Lookup xs k (State s) => Proxy k -> Eff xs s
- getsEff :: forall k s a xs. Lookup xs k (State s) => Proxy k -> (s -> a) -> Eff xs a
- putEff :: forall k s xs. Lookup xs k (State s) => Proxy k -> s -> Eff xs ()
- modifyEff :: forall k s xs. Lookup xs k (State s) => Proxy k -> (s -> s) -> Eff xs ()
- stateEff :: forall k s xs a. Lookup xs k (State s) => Proxy k -> (s -> (a, s)) -> Eff xs a
- runStateEff :: forall k s xs a. Eff ((k >: State s) ': xs) a -> s -> Eff xs (a, s)
- execStateEff :: forall k s xs a. Eff ((k >: State s) ': xs) a -> s -> Eff xs s
- evalStateEff :: forall k s xs a. Eff ((k >: State s) ': xs) a -> s -> Eff xs a
- type WriterEff w = (,) w
- writerEff :: forall k w xs a. Lookup xs k (WriterEff w) => Proxy k -> (a, w) -> Eff xs a
- tellEff :: forall k w xs. Lookup xs k (WriterEff w) => Proxy k -> w -> Eff xs ()
- listenEff :: forall k w xs a. (Lookup xs k (WriterEff w), Monoid w) => Proxy k -> Eff xs a -> Eff xs (a, w)
- passEff :: forall k w xs a. (Lookup xs k (WriterEff w), Monoid w) => Proxy k -> Eff xs (a, w -> w) -> Eff xs a
- runWriterEff :: forall k w xs a. Monoid w => Eff ((k >: WriterEff w) ': xs) a -> Eff xs (a, w)
- execWriterEff :: forall k w xs a. Monoid w => Eff ((k >: WriterEff w) ': xs) a -> Eff xs w
- type MaybeEff = Const ()
- nothingEff :: Lookup xs k MaybeEff => Proxy k -> Eff xs a
- runMaybeEff :: forall k xs a. Eff ((k >: MaybeEff) ': xs) a -> Eff xs (Maybe a)
- type EitherEff = Const
- throwEff :: Lookup xs k (EitherEff e) => Proxy k -> e -> Eff xs a
- catchEff :: forall k e xs a. Lookup xs k (EitherEff e) => Proxy k -> Eff xs a -> (e -> Eff xs a) -> Eff xs a
- runEitherEff :: forall k e xs a. Eff ((k >: EitherEff e) ': xs) a -> Eff xs (Either e a)
- mapLeftEff :: (e -> e') -> Eff ((k >: EitherEff e) ': xs) a -> Eff ((k >: EitherEff e') ': xs) a
- data Identity a
- tickEff :: Lookup xs k Identity => Proxy k -> Eff xs ()
- runIterEff :: Eff ((k >: Identity) ': xs) a -> Eff xs (Either a (Eff ((k >: Identity) ': xs) a))
- data ContT (r :: k) (m :: k -> Type) a
- contEff :: Lookup xs k (ContT r m) => Proxy k -> ((a -> m r) -> m r) -> Eff xs a
- runContEff :: forall k r xs a. Eff ((k >: ContT r (Eff xs)) ': xs) a -> (a -> Eff xs r) -> Eff xs r
- callCCEff :: Proxy k -> ((a -> Eff ((k >: ContT r (Eff xs)) ': xs) b) -> Eff ((k >: ContT r (Eff xs)) ': xs) a) -> Eff ((k >: ContT r (Eff xs)) ': xs) a
Base
data Instruction (xs :: [Assoc k (Type -> Type)]) a where Source #
A unit of named effects. This is a variant of (
specialised for
'Type -> Type'.:|
)
Instruction :: !(Membership xs kv) -> TargetOf kv a -> Instruction xs a |
Instances
type Eff xs = Skeleton (Instruction xs) Source #
The extensible operational monad
liftEff :: forall s t xs a. Lookup xs s t => Proxy s -> t a -> Eff xs a Source #
Lift an instruction onto an Eff
action.
liftsEff :: forall s t xs a r. Lookup xs s t => Proxy s -> t a -> (a -> r) -> Eff xs r Source #
Lift an instruction onto an Eff
action and apply a function to the result.
hoistEff :: forall s t xs a. Lookup xs s t => Proxy s -> (forall x. t x -> t x) -> Eff xs a -> Eff xs a Source #
Censor a specific type of effects in an action.
Step-wise handling
newtype Interpreter f g Source #
Transformation between effects
Interpreter | |
|
handleEff :: RecordOf (Interpreter m) xs -> Eff xs a -> MonadView m (Eff xs) a Source #
Process an Eff
action using a record of Interpreter
s.
Peeling
:: forall k t xs a r. Rebinder xs r | Re-bind an unrelated action |
-> (a -> r) | return the result |
-> (forall x. t x -> (x -> r) -> r) | Handle the foremost type of an action |
-> Eff ((k >: t) ': xs) a | |
-> r |
Build a relay-style handler from a triple of functions.
runStateEff = peelEff1 (a s -> return (a, s)) (m k s -> let (a, s') = runState m s in k a s')
type Rebinder xs r = forall x. Instruction xs x -> (x -> r) -> r Source #
A function to bind an Instruction
in peelEff
.
rebindEff0 :: Rebinder xs (Eff xs r) Source #
A common value for the second argument of peelEff
. Binds an instruction
directly.
:: forall k t xs a r. (a -> Eff xs r) | return the result |
-> (forall x. t x -> (x -> Eff xs r) -> Eff xs r) | Handle the foremost type of an action |
-> Eff ((k >: t) ': xs) a | |
-> Eff xs r |
peelEff
specialised for continuations with no argument
rebindEff1 :: Rebinder xs (a -> Eff xs r) Source #
A pre-defined value for the second argument of peelEff
.
Preserves the argument of the continuation.
:: forall k t xs a b r. (a -> b -> Eff xs r) | return the result |
-> (forall x. t x -> (x -> b -> Eff xs r) -> b -> Eff xs r) | Handle the foremost type of an action |
-> Eff ((k >: t) ': xs) a | |
-> b | |
-> Eff xs r |
peelEff
specialised for 1-argument continuation
rebindEff2 :: Rebinder xs (a -> b -> Eff xs r) Source #
A pre-defined value for the second argument of peelEff
.
Preserves two arguments of the continuation.
retractEff :: forall k m a. Monad m => Eff '[k >: m] a -> m a Source #
Tear down an action using the Monad
instance of the instruction.
Anonymous actions
runAction :: Function xs (f a) -> Action xs a r -> f r Source #
Pass the arguments of Action
to the supplied function.
(@!?) :: FieldName k -> Function xs (f a) -> Field (Interpreter f) (k :> Action xs a) infix 1 Source #
Create a Field
of a Interpreter
for an Action
.
:: forall k ps q xs a r. (forall x. Instruction xs x -> (x -> r) -> r) | Re-bind an unrelated action |
-> (a -> r) | return the result |
-> Function ps ((q -> r) -> r) | Handle the foremost action |
-> Eff ((k >: Action ps q) ': xs) a | |
-> r |
:: forall k ps q xs a. Function ps (Eff xs q) | Handle the foremost action |
-> Eff ((k >: Action ps q) ': xs) a | |
-> Eff xs a |
Non continuation-passing variant of peelAction
.
transformers-compatible actions and handlers
Reader
type ReaderEff = (:~:) Source #
The reader monad is characterised by a type equality between the result type and the enviroment type.
askEff :: forall k r xs. Lookup xs k (ReaderEff r) => Proxy k -> Eff xs r Source #
Fetch the environment.
asksEff :: forall k r xs a. Lookup xs k (ReaderEff r) => Proxy k -> (r -> a) -> Eff xs a Source #
Pass the environment to a function.
localEff :: forall k r xs a. Lookup xs k (ReaderEff r) => Proxy k -> (r -> r) -> Eff xs a -> Eff xs a Source #
Modify the enviroment locally.
runReaderEff :: forall k r xs a. Eff ((k >: ReaderEff r) ': xs) a -> r -> Eff xs a Source #
Run the frontal reader effect.
State
type State s = StateT s Identity #
A state monad parameterized by the type s
of the state to carry.
The return
function leaves the state unchanged, while >>=
uses
the final state of the first computation as the initial state of
the second.
getEff :: forall k s xs. Lookup xs k (State s) => Proxy k -> Eff xs s Source #
Get the current state.
getsEff :: forall k s a xs. Lookup xs k (State s) => Proxy k -> (s -> a) -> Eff xs a Source #
Pass the current state to a function.
putEff :: forall k s xs. Lookup xs k (State s) => Proxy k -> s -> Eff xs () Source #
Replace the state with a new value.
modifyEff :: forall k s xs. Lookup xs k (State s) => Proxy k -> (s -> s) -> Eff xs () Source #
Modify the state.
stateEff :: forall k s xs a. Lookup xs k (State s) => Proxy k -> (s -> (a, s)) -> Eff xs a Source #
Lift a state modification function.
runStateEff :: forall k s xs a. Eff ((k >: State s) ': xs) a -> s -> Eff xs (a, s) Source #
Run the frontal state effect.
execStateEff :: forall k s xs a. Eff ((k >: State s) ': xs) a -> s -> Eff xs s Source #
Run the frontal state effect and return the final state.
evalStateEff :: forall k s xs a. Eff ((k >: State s) ': xs) a -> s -> Eff xs a Source #
Run the frontal state effect and return the final result.
Writer
writerEff :: forall k w xs a. Lookup xs k (WriterEff w) => Proxy k -> (a, w) -> Eff xs a Source #
Write the second element and return the first element.
tellEff :: forall k w xs. Lookup xs k (WriterEff w) => Proxy k -> w -> Eff xs () Source #
Write a value.
listenEff :: forall k w xs a. (Lookup xs k (WriterEff w), Monoid w) => Proxy k -> Eff xs a -> Eff xs (a, w) Source #
Squash the outputs into one step and return it.
passEff :: forall k w xs a. (Lookup xs k (WriterEff w), Monoid w) => Proxy k -> Eff xs (a, w -> w) -> Eff xs a Source #
Modify the output using the function in the result.
runWriterEff :: forall k w xs a. Monoid w => Eff ((k >: WriterEff w) ': xs) a -> Eff xs (a, w) Source #
Run the frontal writer effect.
execWriterEff :: forall k w xs a. Monoid w => Eff ((k >: WriterEff w) ': xs) a -> Eff xs w Source #
Run the frontal state effect.
Maybe
nothingEff :: Lookup xs k MaybeEff => Proxy k -> Eff xs a Source #
Break out of the computation. Similar to Nothing
.
runMaybeEff :: forall k xs a. Eff ((k >: MaybeEff) ': xs) a -> Eff xs (Maybe a) Source #
Run an effect which may fail in the name of k
.
Either
throwEff :: Lookup xs k (EitherEff e) => Proxy k -> e -> Eff xs a Source #
Throw an exception e
, throwing the rest of the computation away.
catchEff :: forall k e xs a. Lookup xs k (EitherEff e) => Proxy k -> Eff xs a -> (e -> Eff xs a) -> Eff xs a Source #
Attach a handler for an exception.
runEitherEff :: forall k e xs a. Eff ((k >: EitherEff e) ': xs) a -> Eff xs (Either e a) Source #
Run an action and abort on throwEff
.
mapLeftEff :: (e -> e') -> Eff ((k >: EitherEff e) ': xs) a -> Eff ((k >: EitherEff e') ': xs) a Source #
Take a function and applies it to an Either effect iff the effect takes the form Left _.
Iter
Identity functor and monad. (a non-strict monad)
Since: base-4.8.0.0
Instances
runIterEff :: Eff ((k >: Identity) ': xs) a -> Eff xs (Either a (Eff ((k >: Identity) ': xs) a)) Source #
Run a computation until the first call of tickEff
.
Cont
data ContT (r :: k) (m :: k -> Type) a #
The continuation monad transformer.
Can be used to add continuation handling to any type constructor:
the Monad
instance and most of the operations do not require m
to be a monad.
ContT
is not a functor on the category of monads, and many operations
cannot be lifted through it.
Instances
MonadState s m => MonadState s (ContT r m) | |
MonadReader r' m => MonadReader r' (ContT r m) | |
MonadTrans (ContT r) | |
Defined in Control.Monad.Trans.Cont | |
MonadCont (Eff (ContDef r (Eff xs) ': xs)) Source # | |
Monad (ContT r m) | |
Functor (ContT r m) | |
MonadFail m => MonadFail (ContT r m) | |
Defined in Control.Monad.Trans.Cont | |
Applicative (ContT r m) | |
MonadIO m => MonadIO (ContT r m) | |
Defined in Control.Monad.Trans.Cont | |
MonadThrow m => MonadThrow (ContT r m) | |
Defined in Control.Monad.Catch | |
MonadCont (ContT r m) | |
PrimMonad m => PrimMonad (ContT r m) | Since: primitive-0.6.3.0 |
MonadResource m => MonadResource (ContT r m) | |
Defined in Control.Monad.Trans.Resource.Internal liftResourceT :: ResourceT IO a -> ContT r m a # | |
type PrimState (ContT r m) | |
Defined in Control.Monad.Primitive |
contEff :: Lookup xs k (ContT r m) => Proxy k -> ((a -> m r) -> m r) -> Eff xs a Source #
Place a continuation-passing action.