Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- class Monad m => Algebra sig m | m -> sig where
- thread :: (Functor ctx1, Functor ctx2, Algebra sig m) => Handler (Compose ctx1 ctx2) n m -> sig n a -> ctx1 (ctx2 ()) -> m (ctx1 (ctx2 a))
- run :: Identity a -> a
- type Has eff sig m = (Members eff sig, Algebra sig m)
- send :: (Member eff sig, Algebra sig m) => eff m a -> m a
- type Handler ctx m n = forall x. ctx (m x) -> n (ctx x)
- (~<~) :: (Functor n, Functor ctx1) => Handler ctx1 m n -> Handler ctx2 l m -> Handler (Compose ctx1 ctx2) l n
- data (f :+: g) (m :: Type -> Type) k
Documentation
class Monad m => Algebra sig m | m -> sig where Source #
The class of carriers (results) for algebras (effect handlers) over signatures (effects), whose actions are given by the alg
method.
Since: 1.0.0.0
:: Functor ctx | |
=> Handler ctx n m | A |
-> sig n a | The effect signature to be interpreted. |
-> ctx () | The initial state. |
-> m (ctx a) | The interpretation of the effect in |
Interpret an effect, running any nested actions using a Handler
starting from an initial state in ctx
.
Instances receive a signature of effects containing actions in n
which can be lowered to m
using the passed Handler
and initial context. Continuations in n
can be handled after mapping into contexts returned from previous actions.
For example, considering the Algebra
instance for
:Either
e
instance Algebra (Error e) (Either e) where alg hdl sig ctx = case sig of L (Throw e) -> Left e R (Catch m h) -> either (hdl . (<$ ctx) . h) pure (hdl (m <$ ctx))
The Catch
case holds actions m :: n x
and h :: e -> n x
(for some existentially-quantified type x
), and a continuation k :: x -> n a
. The algebra must return m (ctx a)
, so we have to ultimately use and lower the continuation in order to produce that type. The continuation takes an x
, which we can get from either of the actions, after lowering them to values in
.Either
e
To that end, the algebra lifts both the action m
and the result of the error handler h
into the initial context ctx
before lowering them with hdl
. The continuation k
is fmap
ed into the resulting context and then itself lowered with hdl
.
By contrast, the Throw
case can simply return a value in Left
, since there is no continuation to call—it represents an exceptional return—and
(i.e. Left
e :: forall a . Either e aLeft
is polymorphic in a
).
Instances for monad transformers will most likely handle a signature containing multiple effects, with the tail of the signature handled by whatever monad the transformer wraps. In these cases, the tail of the signature can be delegated most conveniently using thread
; see the Algebra
instances for transformers
types such as ReaderT
and ExceptT
for details.
Instances
Algebra Choose NonEmpty Source # | |
Algebra Empty Maybe Source # | |
Algebra NonDet [] Source # | |
Algebra sig m => Algebra sig (Alt m) Source # | This instance permits effectful actions to be lifted into the a <|> b <|> c <|> d is equivalent to getAlt (mconcat [a, b, c, d]) Since: 1.0.1.0 |
Algebra sig m => Algebra sig (Ap m) Source # | This instance permits effectful actions to be lifted into the mappend <$> act1 <*> (mappend <$> act2 <*> act3) is equivalent to getAp (act1 <> act2 <> act3) Since: 1.0.1.0 |
Algebra sig m => Algebra sig (IdentityT m) Source # | |
Algebra (Lift IO) IO Source # | |
Algebra (Lift Identity) Identity Source # | |
Monad m => Algebra (Lift m) (LiftC m) Source # | |
Algebra (Error e) (Either e) Source # | |
Monoid w => Algebra (Writer w) ((,) w) Source # | |
Algebra (Reader r) ((->) r :: Type -> Type) Source # | |
Algebra sig m => Algebra (Choose :+: sig) (ChooseC m) Source # | |
Algebra sig m => Algebra (Empty :+: sig) (MaybeT m) Source # | |
Algebra sig m => Algebra (Empty :+: sig) (EmptyC m) Source # | |
Algebra sig m => Algebra (Empty :+: sig) (EmptyC m) Source # | |
Algebra sig m => Algebra (NonDet :+: sig) (NonDetC m) Source # | |
(MonadIO m, Algebra sig m) => Algebra (Trace :+: sig) (TraceC m) Source # | |
Algebra sig m => Algebra (Trace :+: sig) (TraceC m) Source # | |
Algebra sig m => Algebra (Trace :+: sig) (TraceC m) Source # | |
Algebra sig m => Algebra (Fail :+: sig) (FailC m) Source # | |
Algebra sig m => Algebra (Fresh :+: sig) (FreshC m) Source # | |
Algebra sig m => Algebra (Fresh :+: sig) (FreshC m) Source # | |
Algebra sig m => Algebra (Cut :+: (NonDet :+: sig)) (CutC m) Source # | |
Algebra sig m => Algebra (Cull :+: (NonDet :+: sig)) (CullC m) Source # | |
Algebra sig m => Algebra (Reader r :+: sig) (ReaderC r m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateT s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateT s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateC s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateC s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateC s m) Source # | |
Algebra sig m => Algebra (Throw e :+: sig) (ThrowC e m) Source # | |
Algebra sig m => Algebra (Error e :+: sig) (ExceptT e m) Source # | |
Algebra sig m => Algebra (Error e :+: sig) (ErrorC e m) Source # | |
Algebra sig m => Algebra (Error e :+: sig) (ErrorC e m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Writer w :+: sig) (WriterT w m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Writer w :+: sig) (WriterT w m) Source # | |
(Monoid w, Algebra sig m) => Algebra (Writer w :+: sig) (WriterC w m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Writer w :+: sig) (WriterC w m) Source # | |
(Reifies s (Interpreter eff m), Algebra sig m) => Algebra (eff :+: sig) (InterpretC s eff m) Source # | |
Defined in Control.Carrier.Interpret alg :: Functor ctx => Handler ctx n (InterpretC s eff m) -> (eff :+: sig) n a -> ctx () -> InterpretC s eff m (ctx a) Source # | |
Algebra sig m => Algebra (Reader r :+: sig) (ReaderT r m) Source # | |
(LabelledMember label sub sig, Algebra sig m) => Algebra (sub :+: sig) (UnderLabel label sub m) Source # | |
Defined in Control.Effect.Labelled alg :: Functor ctx => Handler ctx n (UnderLabel label sub m) -> (sub :+: sig) n a -> ctx () -> UnderLabel label sub m (ctx a) Source # | |
(Algebra sig m, Monoid w) => Algebra (Reader r :+: (Writer w :+: (State s :+: sig))) (RWST r w s m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Reader r :+: (Writer w :+: (State s :+: sig))) (RWST r w s m) Source # | |
Algebra (eff :+: sig) (sub m) => Algebra (Labelled label eff :+: sig) (Labelled label sub m) Source # | |
thread :: (Functor ctx1, Functor ctx2, Algebra sig m) => Handler (Compose ctx1 ctx2) n m -> sig n a -> ctx1 (ctx2 ()) -> m (ctx1 (ctx2 a)) Source #
Thread a composed handler and input state through the algebra for some underlying signature.
Since: 1.1.0.0
run :: Identity a -> a Source #
Run an action exhausted of effects to produce its final result value.
Since: 1.0.0.0
type Has eff sig m = (Members eff sig, Algebra sig m) Source #
m
is a carrier for sig
containing eff
.
Note that if eff
is a sum, it will be decomposed into multiple Member
constraints. While this technically allows one to combine multiple unrelated effects into a single Has
constraint, doing so has two significant drawbacks:
- Due to a problem with recursive type families, this can lead to significantly slower compiles.
- It defeats
ghc
’s warnings for redundant constraints, and thus can lead to a proliferation of redundant constraints as code is changed.
Since: 1.0.0.0
send :: (Member eff sig, Algebra sig m) => eff m a -> m a Source #
Construct a request for an effect to be interpreted by some handler later on.
Since: 0.1.0.0
Re-exports
type Handler ctx m n = forall x. ctx (m x) -> n (ctx x) Source #
Handlers take an action in m
bundled up with some state in some context functor ctx
, and return an action in n
producing a derived state in ctx
.
These are expected to be well-behaved distributive laws, and are required to adhere to the following laws:
handler.
fmap
pure
=pure
handler.
fmap
(k=<<
) = handler.
fmap
k<=<
handler
respectively expressing that the handler does not alter the context of pure computations, and that the handler distributes over monadic composition.
Handlers compose with handlers, using e.g. Data.Functor.Compose.
to ensure that the result is itself well-typed as a Compose
Handler
:
fmap
Compose
.
handler1.
fmap
handler2.
getCompose
and with monad homomorphisms on the left and right:
hom .
handler
handler.
fmap
hom
Since: 1.1.0.0
(~<~) :: (Functor n, Functor ctx1) => Handler ctx1 m n -> Handler ctx2 l m -> Handler (Compose ctx1 ctx2) l n infixr 1 Source #
Composition of handlers.
Since: 1.1.0.0
data (f :+: g) (m :: Type -> Type) k infixr 4 Source #
Higher-order sums are used to combine multiple effects into a signature, typically by chaining on the right.
Instances
Algebra NonDet [] Source # | |
LabelledMember label l r => LabelledMember (label :: k) l (l' :+: r) Source # | Right-recursion: if |
Defined in Control.Effect.Labelled injLabelled :: Labelled label l m a -> (l' :+: r) m a Source # | |
LabelledMember (label :: k) l (Labelled label l :+: r) Source # | Left-occurrence: if |
Defined in Control.Effect.Labelled | |
LabelledMember label t (l1 :+: (l2 :+: r)) => LabelledMember (label :: k) t ((l1 :+: l2) :+: r) Source # | Left-recursion: if |
Defined in Control.Effect.Labelled | |
Member l r => Member l (l' :+: r) Source # | Right-recursion: if |
Defined in Control.Effect.Sum | |
Member l (l :+: r) Source # | Left-occurrence: if |
Defined in Control.Effect.Sum | |
Member t (l1 :+: (l2 :+: r)) => Member t ((l1 :+: l2) :+: r) Source # | Left-recursion: if |
Algebra (Error e) (Either e) Source # | |
Algebra sig m => Algebra (Choose :+: sig) (ChooseC m) Source # | |
Algebra sig m => Algebra (Empty :+: sig) (MaybeT m) Source # | |
Algebra sig m => Algebra (Empty :+: sig) (EmptyC m) Source # | |
Algebra sig m => Algebra (Empty :+: sig) (EmptyC m) Source # | |
Algebra sig m => Algebra (NonDet :+: sig) (NonDetC m) Source # | |
(MonadIO m, Algebra sig m) => Algebra (Trace :+: sig) (TraceC m) Source # | |
Algebra sig m => Algebra (Trace :+: sig) (TraceC m) Source # | |
Algebra sig m => Algebra (Trace :+: sig) (TraceC m) Source # | |
Algebra sig m => Algebra (Fail :+: sig) (FailC m) Source # | |
Algebra sig m => Algebra (Fresh :+: sig) (FreshC m) Source # | |
Algebra sig m => Algebra (Fresh :+: sig) (FreshC m) Source # | |
Algebra sig m => Algebra (Cut :+: (NonDet :+: sig)) (CutC m) Source # | |
Algebra sig m => Algebra (Cull :+: (NonDet :+: sig)) (CullC m) Source # | |
Algebra sig m => Algebra (Reader r :+: sig) (ReaderC r m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateT s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateT s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateC s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateC s m) Source # | |
Algebra sig m => Algebra (State s :+: sig) (StateC s m) Source # | |
Algebra sig m => Algebra (Throw e :+: sig) (ThrowC e m) Source # | |
Algebra sig m => Algebra (Error e :+: sig) (ExceptT e m) Source # | |
Algebra sig m => Algebra (Error e :+: sig) (ErrorC e m) Source # | |
Algebra sig m => Algebra (Error e :+: sig) (ErrorC e m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Writer w :+: sig) (WriterT w m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Writer w :+: sig) (WriterT w m) Source # | |
(Monoid w, Algebra sig m) => Algebra (Writer w :+: sig) (WriterC w m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Writer w :+: sig) (WriterC w m) Source # | |
(Reifies s (Interpreter eff m), Algebra sig m) => Algebra (eff :+: sig) (InterpretC s eff m) Source # | |
Defined in Control.Carrier.Interpret alg :: Functor ctx => Handler ctx n (InterpretC s eff m) -> (eff :+: sig) n a -> ctx () -> InterpretC s eff m (ctx a) Source # | |
Algebra sig m => Algebra (Reader r :+: sig) (ReaderT r m) Source # | |
(LabelledMember label sub sig, Algebra sig m) => Algebra (sub :+: sig) (UnderLabel label sub m) Source # | |
Defined in Control.Effect.Labelled alg :: Functor ctx => Handler ctx n (UnderLabel label sub m) -> (sub :+: sig) n a -> ctx () -> UnderLabel label sub m (ctx a) Source # | |
(Algebra sig m, Monoid w) => Algebra (Reader r :+: (Writer w :+: (State s :+: sig))) (RWST r w s m) Source # | |
(Algebra sig m, Monoid w) => Algebra (Reader r :+: (Writer w :+: (State s :+: sig))) (RWST r w s m) Source # | |
Algebra (eff :+: sig) (sub m) => Algebra (Labelled label eff :+: sig) (Labelled label sub m) Source # | |
(Functor (f m), Functor (g m)) => Functor ((f :+: g) m) Source # | |
(Foldable (f m), Foldable (g m)) => Foldable ((f :+: g) m) Source # | |
Defined in Control.Effect.Sum fold :: Monoid m0 => (f :+: g) m m0 -> m0 # foldMap :: Monoid m0 => (a -> m0) -> (f :+: g) m a -> m0 # foldr :: (a -> b -> b) -> b -> (f :+: g) m a -> b # foldr' :: (a -> b -> b) -> b -> (f :+: g) m a -> b # foldl :: (b -> a -> b) -> b -> (f :+: g) m a -> b # foldl' :: (b -> a -> b) -> b -> (f :+: g) m a -> b # foldr1 :: (a -> a -> a) -> (f :+: g) m a -> a # foldl1 :: (a -> a -> a) -> (f :+: g) m a -> a # toList :: (f :+: g) m a -> [a] # null :: (f :+: g) m a -> Bool # length :: (f :+: g) m a -> Int # elem :: Eq a => a -> (f :+: g) m a -> Bool # maximum :: Ord a => (f :+: g) m a -> a # minimum :: Ord a => (f :+: g) m a -> a # | |
(Traversable (f m), Traversable (g m)) => Traversable ((f :+: g) m) Source # | |
Defined in Control.Effect.Sum | |
(Eq (f m k), Eq (g m k)) => Eq ((f :+: g) m k) Source # | |
(Ord (f m k), Ord (g m k)) => Ord ((f :+: g) m k) Source # | |
Defined in Control.Effect.Sum compare :: (f :+: g) m k -> (f :+: g) m k -> Ordering # (<) :: (f :+: g) m k -> (f :+: g) m k -> Bool # (<=) :: (f :+: g) m k -> (f :+: g) m k -> Bool # (>) :: (f :+: g) m k -> (f :+: g) m k -> Bool # (>=) :: (f :+: g) m k -> (f :+: g) m k -> Bool # | |
(Show (f m k), Show (g m k)) => Show ((f :+: g) m k) Source # | |