| Safe Haskell | Safe | 
|---|---|
| Language | Haskell2010 | 
Control.Eff
Description
A monadic library for implementing effectful computation in a modular way.
This module provides the Eff monad - the base type for all effectful
 computation.
 The Member typeclass is the main interface for describing which effects
 are necessary for a given function.
Consult the Control.Eff.QuickStart module and the readme for gentle
 introductions.
To use extensible effects effectively some language extensions are necessary/recommended.
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
Synopsis
- run :: Eff '[] w -> w
 - data Eff r a
 - lift :: Lifted m r => m a -> Eff r a
 - runLift :: Monad m => Eff '[Lift m] w -> m w
 - catchDynE :: forall e a r. (Lifted IO r, Exception e) => Eff r a -> (e -> Eff r a) -> Eff r a
 - data HandlerDynE r a = (Exception e, Lifted IO r) => HandlerDynE (e -> Eff r a)
 - catchesDynE :: Lifted IO r => Eff r a -> [HandlerDynE r a] -> Eff r a
 - newtype Lift m a = Lift {
- unLift :: m a
 
 - type Lifted m r = SetMember Lift (Lift m) r
 - type LiftedBase m r = (SetMember Lift (Lift m) r, MonadBaseControl m (Eff r))
 - class FindElem t r => Member (t :: * -> *) r
 - class Member t r => SetMember (tag :: k -> * -> *) (t :: * -> *) r | tag r -> t
 - type family (ms :: [* -> *]) <:: r where ...
 
Effect type
run :: Eff '[] w -> w Source #
Get the result from a pure computation
A pure computation has type Eff '[] a. The empty effect-list indicates that
 no further effects need to be handled.
The monad that all effects in this library are based on.
An effectful computation is a value of type `Eff r a`.
 In this signature, r is a type-level list of effects that are being
 requested and need to be handled inside an effectful computation.
 a is the computation's result similar to other monads.
A computation's result can be retrieved via the run function.
 However, all effects used in the computation need to be handled by the use
 of the effects' run* functions before unwrapping the final result.
 For additional details, see the documentation of the effects you are using.
Instances
| Alternative f => Handle NDet r a ([Eff r a] -> Eff r' (f w)) Source # | More performant handler; uses reified job queue  | 
Defined in Control.Eff.Logic.NDet Methods handle :: (Eff r a -> [Eff r a] -> Eff r' (f w)) -> Arrs r v a -> NDet v -> [Eff r a] -> Eff r' (f w) Source # handle_relay :: (r ~ (NDet ': r'0), Relay ([Eff r a] -> Eff r' (f w)) r'0) => (a -> [Eff r a] -> Eff r' (f w)) -> (Eff r a -> [Eff r a] -> Eff r' (f w)) -> Eff r a -> [Eff r a] -> Eff r' (f w) Source # respond_relay :: (a -> [Eff r a] -> Eff r' (f w)) -> (Eff r a -> [Eff r a] -> Eff r' (f w)) -> Eff r a -> [Eff r a] -> Eff r' (f w) Source #  | |
| Alternative f => Handle NDet r a (Eff r' (f w)) Source # | Given a callback and   | 
Defined in Control.Eff.Logic.NDet Methods handle :: (Eff r a -> Eff r' (f w)) -> Arrs r v a -> NDet v -> Eff r' (f w) Source # handle_relay :: (r ~ (NDet ': r'0), Relay (Eff r' (f w)) r'0) => (a -> Eff r' (f w)) -> (Eff r a -> Eff r' (f w)) -> Eff r a -> Eff r' (f w) Source # respond_relay :: (a -> Eff r' (f w)) -> (Eff r a -> Eff r' (f w)) -> Eff r a -> Eff r' (f w) Source #  | |
| (MonadBase b m, Lifted m r) => MonadBase b (Eff r) Source # | |
Defined in Control.Eff.Internal  | |
| MonadBase m m => MonadBaseControl m (Eff (Lift m ': ([] :: [Type -> Type]))) Source # | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff (Writer w ': r)) Source # | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff (Writer w ': r)) Source # | |
| (MonadBase m m, LiftedBase m s) => MonadBaseControl m (Eff (Reader e ': s)) Source # | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff (State s ': r)) Source # | |
| (MonadBase m m, LiftedBase m s) => MonadBaseControl m (Eff (Reader e ': s)) Source # | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff (State s ': r)) Source # | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff (OnDemandState s ': r)) Source # | |
Defined in Control.Eff.State.OnDemand Associated Types type StM (Eff (OnDemandState s ': r)) a :: Type # Methods liftBaseWith :: (RunInBase (Eff (OnDemandState s ': r)) m -> m a) -> Eff (OnDemandState s ': r) a # restoreM :: StM (Eff (OnDemandState s ': r)) a -> Eff (OnDemandState s ': r) a #  | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff (Fresh ': r)) Source # | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff ((Exc e :: Type -> Type) ': r)) Source # | |
| (MonadBase m m, LiftedBase m r) => MonadBaseControl m (Eff (NDet ': r)) Source # | |
| Monad (Eff r) Source # | |
| Functor (Eff r) Source # | |
| Applicative (Eff r) Source # | |
| (MonadIO m, Lifted m r) => MonadIO (Eff r) Source # | |
Defined in Control.Eff.Internal  | |
| Member NDet r => Alternative (Eff r) Source # | |
| Member NDet r => MonadPlus (Eff r) Source # | Mapping of  mzero >>= f = mzero -- (L1) mzero `mplus` m = m -- (L2) m `mplus` mzero = m -- (L3) m `mplus` (n `mplus` o) = (m `mplus` n) `mplus` o -- (L4) (m `mplus` n) >>= k = (m >>= k) `mplus` (n >>= k) -- (L5) 
 NOTE that we do not obey the right-zero law for
  m >> mzero = mzero  | 
| Member NDet r => MSplit (Eff r) Source # | We implement LogicT, the non-determinism reflection, of which soft-cut is one instance. See the LogicT paper for an explanation.  | 
| Relay (Eff r w) r Source # | |
| Handle (Program f) r a (Intrprtr f r' -> Eff r' a) Source # | Given a continuation and a program, interpret it
 Usually, we have   | 
Defined in Control.Eff.Operational Methods handle :: (Eff r a -> Intrprtr f r' -> Eff r' a) -> Arrs r v a -> Program f v -> Intrprtr f r' -> Eff r' a Source # handle_relay :: (r ~ (Program f ': r'0), Relay (Intrprtr f r' -> Eff r' a) r'0) => (a -> Intrprtr f r' -> Eff r' a) -> (Eff r a -> Intrprtr f r' -> Eff r' a) -> Eff r a -> Intrprtr f r' -> Eff r' a Source # respond_relay :: (a -> Intrprtr f r' -> Eff r' a) -> (Eff r a -> Intrprtr f r' -> Eff r' a) -> Eff r a -> Intrprtr f r' -> Eff r' a Source #  | |
| Handle (Yield a b) (Yield a b ': r) w (Eff r (Y r b a)) Source # | Given a continuation and a request, respond to it  | 
Defined in Control.Eff.Coroutine Methods handle :: (Eff (Yield a b ': r) w -> Eff r (Y r b a)) -> Arrs (Yield a b ': r) v w -> Yield a b v -> Eff r (Y r b a) Source # handle_relay :: ((Yield a b ': r) ~ (Yield a b ': r'), Relay (Eff r (Y r b a)) r') => (w -> Eff r (Y r b a)) -> (Eff (Yield a b ': r) w -> Eff r (Y r b a)) -> Eff (Yield a b ': r) w -> Eff r (Y r b a) Source # respond_relay :: (w -> Eff r (Y r b a)) -> (Eff (Yield a b ': r) w -> Eff r (Y r b a)) -> Eff (Yield a b ': r) w -> Eff r (Y r b a) Source #  | |
| type StM (Eff (Lift m ': ([] :: [Type -> Type]))) a Source # | |
| type StM (Eff (Writer w ': r)) a Source # | |
| type StM (Eff (Writer w ': r)) a Source # | |
| type StM (Eff (Reader e ': s)) a Source # | |
| type StM (Eff (State s ': r)) a Source # | |
| type StM (Eff (Reader e ': s)) a Source # | |
| type StM (Eff (State s ': r)) a Source # | |
| type StM (Eff (OnDemandState s ': r)) a Source # | |
Defined in Control.Eff.State.OnDemand  | |
| type StM (Eff (Fresh ': r)) a Source # | |
| type StM (Eff ((Exc e :: Type -> Type) ': r)) a Source # | |
| type StM (Eff (NDet ': r)) a Source # | |
Lift IO computations
lift :: Lifted m r => m a -> Eff r a Source #
embed an operation of type `m a` into the Eff monad when Lift m is in
 a part of the effect-list.
runLift :: Monad m => Eff '[Lift m] w -> m w Source #
The handler of Lift requests. It is meant to be terminal: we only allow a single Lifted Monad. Note, too, how this is different from other handlers.
catchDynE :: forall e a r. (Lifted IO r, Exception e) => Eff r a -> (e -> Eff r a) -> Eff r a Source #
Catching of dynamic exceptions See the problem in http://okmij.org/ftp/Haskell/misc.html#catch-MonadIO
data HandlerDynE r a Source #
You need this when using catchesDynE.
Constructors
| (Exception e, Lifted IO r) => HandlerDynE (e -> Eff r a) | 
catchesDynE :: Lifted IO r => Eff r a -> [HandlerDynE r a] -> Eff r a Source #
Catch multiple dynamic exceptions. The implementation follows that in Control.Exception almost exactly. Not yet tested. Could this be useful for control with cut?
Lifting: emulating monad transformers
type Lifted m r = SetMember Lift (Lift m) r Source #
A convenient alias to SetMember Lift (Lift m) r, which allows us
 to assert that the lifted type occurs ony once in the effect list.
type LiftedBase m r = (SetMember Lift (Lift m) r, MonadBaseControl m (Eff r)) Source #
Same as Lifted but with additional MonadBaseControl constraint
Effect list
class FindElem t r => Member (t :: * -> *) r Source #
Typeclass that asserts that effect t is contained inside the effect-list
 r.
The FindElem typeclass is an implementation detail and not required for
 using the effect list or implementing custom effects.
Instances
| FindElem t r => Member t r Source # | |
| t ~ s => Member t (s ': ([] :: [Type -> Type])) Source # | Explicit type-level equality condition is a dirty
 hack to eliminate the type annotation in the trivial case,
 such as  There is no ambiguity when finding instances for
  The only case we have to concerned about is    | 
class Member t r => SetMember (tag :: k -> * -> *) (t :: * -> *) r | tag r -> t Source #
This class is used for emulating monad transformers
type family (ms :: [* -> *]) <:: r where ... Source #
A useful operator for reducing boilerplate in signatures.
The following lines are equivalent.
(Member (Exc e) r, Member (State s) r) => ... [ Exc e, State s ] r = ...
Equations
| '[] <:: r = (() :: Constraint) | |
| (m ': ms) <:: r = (Member m r, (<::) ms r) |