| Safe Haskell | Safe-Inferred |
|---|---|
| Language | GHC2021 |
Effectful.Internal.Monad
Description
The Eff monad.
This module is intended for internal use only, and may change without warning in subsequent releases.
Synopsis
- data Eff (es :: [Effect]) a
- runPureEff :: HasCallStack => Eff '[] a -> a
- unEff :: Eff es a -> Env es -> IO a
- unsafeEff :: (Env es -> IO a) -> Eff es a
- unsafeEff_ :: IO a -> Eff es a
- data NonDet :: Effect where
- data Fail :: Effect where
- data IOE :: Effect
- runEff :: HasCallStack => Eff '[IOE] a -> IO a
- data Prim :: Effect
- data PrimStateEff
- runPrim :: (HasCallStack, IOE :> es) => Eff (Prim : es) a -> Eff es a
- raise :: forall e es a. Eff es a -> Eff (e : es) a
- raiseWith :: HasCallStack => UnliftStrategy -> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a) -> Eff (e : es) a
- subsume :: e :> es => Eff (e : es) a -> Eff es a
- inject :: Subset subEs es => Eff subEs a -> Eff es a
- class KnownPrefix es => Subset (subEs :: [Effect]) (es :: [Effect])
- data UnliftStrategy
- data Persistence
- data Limit
- unliftStrategy :: (HasCallStack, IOE :> es) => Eff es UnliftStrategy
- withUnliftStrategy :: (HasCallStack, IOE :> es) => UnliftStrategy -> Eff es a -> Eff es a
- withSeqEffToIO :: (HasCallStack, IOE :> es) => ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
- withEffToIO :: (HasCallStack, IOE :> es) => UnliftStrategy -> ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
- reallyUnsafeLiftMapIO :: (IO a -> IO b) -> Eff es a -> Eff es b
- reallyUnsafeUnliftIO :: ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a
- seqUnliftIO :: HasCallStack => Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
- seqForkUnliftIO :: HasCallStack => Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
- concUnliftIO :: HasCallStack => Env es -> Persistence -> Limit -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
- seqForkUnliftsIO :: HasCallStack => Env es -> Env localEs -> ((forall r. Eff es r -> IO r) -> (forall r. Eff localEs r -> IO r) -> IO a) -> IO a
- concUnliftsIO :: HasCallStack => Env es -> Env localEs -> Persistence -> Limit -> ((forall r. Eff es r -> IO r) -> (forall r. Eff localEs r -> IO r) -> IO a) -> IO a
- type EffectHandler (e :: Effect) (es :: [Effect]) = forall a localEs. (HasCallStack, e :> localEs) => LocalEnv localEs -> e (Eff localEs) a -> Eff es a
- data LocalEnv (localEs :: [Effect])
- unwrapLocalEnv :: HasCallStack => Env es -> LocalEnv localEs -> IO (Env localEs)
- requireMatchingStorages :: HasCallStack => Env es -> LocalEnv localEs -> IO ()
- data Handler :: Effect -> Type where
- Handler :: !(Env handlerEs) -> !(HandlerImpl e handlerEs) -> Handler e
- newtype HandlerImpl e es = HandlerImpl (EffectHandler e es)
- relinkHandler :: Relinker Handler e
- runHandler :: (HasCallStack, DispatchOf e ~ Dynamic) => Handler e -> Eff (e : es) a -> Eff es a
- send :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) => e (Eff es) a -> Eff es a
- data family StaticRep (e :: Effect) :: Type
- type family MaybeIOE (sideEffects :: SideEffects) (es :: [Effect]) :: Constraint where ...
- runStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (a, StaticRep e)
- evalStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es a
- execStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) => StaticRep e -> Eff (e : es) a -> Eff es (StaticRep e)
- getStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e)
- putStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es ()
- stateStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> (a, StaticRep e)) -> Eff es a
- stateStaticRepM :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> Eff es (a, StaticRep e)) -> Eff es a
- localStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => (StaticRep e -> StaticRep e) -> Eff es a -> Eff es a
The Eff monad
data Eff (es :: [Effect]) a Source #
The Eff monad provides the implementation of a computation that performs
an arbitrary set of effects. In , Eff es aes is a type-level list that
contains all the effects that the computation may perform. For example, a
computation that produces an Integer by consuming a String from the
global environment and acting upon a single mutable value of type Bool
would have the following type:
(ReaderString:>es,StateBool:>es) =>EffesInteger
Abstracting over the list of effects with (:>):
- Allows the computation to be used in functions that may perform other effects.
- Allows the effects to be handled in any order.
Instances
| IOE :> es => MonadBaseControl IO (Eff es) Source # | Instance included for compatibility with existing code. Usage of Note: the unlifting strategy for |
Defined in Effectful.Internal.Monad Associated Types type StM (Eff es) a | |
| (Show e, Error e :> es, MonadError e (Eff es)) => MonadError e (Eff es) Source # | Instance included for compatibility with existing code. |
Defined in Effectful.Internal.Effect.Dynamic | |
| (Reader r :> es, MonadReader r (Eff es)) => MonadReader r (Eff es) Source # | Instance included for compatibility with existing code. |
| (State s :> es, MonadState s (Eff es)) => MonadState s (Eff es) Source # | Instance included for compatibility with existing code. |
| (Monoid w, Writer w :> es, MonadWriter w (Eff es)) => MonadWriter w (Eff es) Source # | Instance included for compatibility with existing code. Warning: |
| IOE :> es => MonadBase IO (Eff es) Source # | Instance included for compatibility with existing code. Usage of |
Defined in Effectful.Internal.Monad | |
| Fail :> es => MonadFail (Eff es) Source # | |
Defined in Effectful.Internal.Monad | |
| MonadFix (Eff es) Source # | |
Defined in Effectful.Internal.Monad | |
| IOE :> es => MonadIO (Eff es) Source # | |
Defined in Effectful.Internal.Monad | |
| NonDet :> es => Alternative (Eff es) Source # | Since: 2.2.0.0 |
| Applicative (Eff es) Source # | |
| Functor (Eff es) Source # | |
| Monad (Eff es) Source # | |
| NonDet :> es => MonadPlus (Eff es) Source # | Since: 2.2.0.0 |
| MonadCatch (Eff es) Source # | Available without any effect requirements. This is the one instance of the three that would arguably benefit from
requiring For the full discussion see issue #76. |
Defined in Effectful.Internal.Monad | |
| MonadMask (Eff es) Source # | Available without any effect requirements. This makes it possible to use cleanup functions such as
transactionally :: forall s es a. Requiring |
Defined in Effectful.Internal.Monad Methods mask :: HasCallStack => ((forall a. Eff es a -> Eff es a) -> Eff es b) -> Eff es b # uninterruptibleMask :: HasCallStack => ((forall a. Eff es a -> Eff es a) -> Eff es b) -> Eff es b # generalBracket :: HasCallStack => Eff es a -> (a -> ExitCase b -> Eff es c) -> (a -> Eff es b) -> Eff es (b, c) # | |
| MonadThrow (Eff es) Source # | Available without any effect requirements. Gating it behind an effect (such as |
Defined in Effectful.Internal.Monad Methods throwM :: (HasCallStack, Exception e) => e -> Eff es a # | |
| Prim :> es => PrimMonad (Eff es) Source # | |
| IOE :> es => MonadUnliftIO (Eff es) Source # | Instance included for compatibility with existing code. Usage of Note: the unlifting strategy for |
Defined in Effectful.Internal.Monad | |
| Monoid a => Monoid (Eff es a) Source # | |
| Semigroup a => Semigroup (Eff es a) Source # | |
| type PrimState (Eff es) Source # | |
Defined in Effectful.Internal.Monad | |
| type StM (Eff es) a Source # | |
Defined in Effectful.Internal.Monad type StM (Eff es) a = a | |
runPureEff :: HasCallStack => Eff '[] a -> a Source #
Access to the internal representation
unsafeEff_ :: IO a -> Eff es a Source #
NonDet
data NonDet :: Effect where Source #
Provide the ability to use the Alternative and MonadPlus instance for
Eff.
Note: NonDet does not backtrack. Formally, it obeys the "left-catch" law
for MonadPlus, rather than the "left-distribution" law. This means that it
behaves more like Maybe than [].
Since: 2.2.0.0
Instances
| type DispatchOf NonDet Source # | |
Defined in Effectful.Internal.Monad | |
Fail
data Fail :: Effect where Source #
Instances
| type DispatchOf Fail Source # | |
Defined in Effectful.Internal.Monad | |
IO
Run arbitrary IO computations via MonadIO or MonadUnliftIO.
Note: it is not recommended to use this effect in application code as it is too liberal. Ideally, this is only used in handlers of more fine-grained effects.
Instances
| type DispatchOf IOE Source # | |
Defined in Effectful.Internal.Monad | |
| newtype StaticRep IOE Source # | |
Defined in Effectful.Internal.Monad | |
runEff :: HasCallStack => Eff '[IOE] a -> IO a Source #
Run an Eff computation with side effects.
For running pure computations see runPureEff.
Prim
Provide the ability to perform primitive state-transformer actions.
Instances
| type DispatchOf Prim Source # | |
Defined in Effectful.Internal.Monad | |
| data StaticRep Prim Source # | |
Defined in Effectful.Internal.Monad | |
data PrimStateEff Source #
runPrim :: (HasCallStack, IOE :> es) => Eff (Prim : es) a -> Eff es a Source #
Run an Eff computation with primitive state-transformer actions.
Lifting
raise :: forall e es a. Eff es a -> Eff (e : es) a Source #
Lift an Eff computation into an effect stack with one more effect.
Arguments
| :: HasCallStack | |
| => UnliftStrategy | |
| -> ((forall r. Eff (e : es) r -> Eff es r) -> Eff es a) | Continuation with the unlifting function in scope. |
| -> Eff (e : es) a |
Lift an Eff computation into an effect stack with one more effect and
create an unlifting function with the given strategy.
Since: 1.2.0.0
subsume :: e :> es => Eff (e : es) a -> Eff es a Source #
Eliminate a duplicate effect from the top of the effect stack.
inject :: Subset subEs es => Eff subEs a -> Eff es a Source #
Allow for running an effect stack subEs within es as long as subEs is
a permutation (with possible duplicates) of a subset of es.
Generalizes raise and subsume.
>>>data E1 :: Effect>>>data E2 :: Effect>>>data E3 :: Effect
It makes it possible to rearrange the effect stack however you like:
>>>:{shuffle :: Eff (E3 : E1 : E2 : es) a -> Eff (E1 : E2 : E3 : es) a shuffle = inject :}
It can also turn a monomorphic effect stack into a polymorphic one:
>>>:{toPoly :: (E1 :> es, E2 :> es, E3 :> es) => Eff [E1, E2, E3] a -> Eff es a toPoly = inject :}
Moreover, it allows for hiding specific effects from downstream:
>>>:{onlyE1 :: Eff (E1 : es) a -> Eff (E1 : E2 : E3 : es) a onlyE1 = inject :}
>>>:{onlyE2 :: Eff (E2 : es) a -> Eff (E1 : E2 : E3 : es) a onlyE2 = inject :}
>>>:{onlyE3 :: Eff (E3 : es) a -> Eff (E1 : E2 : E3 : es) a onlyE3 = inject :}
However, it's not possible to inject a computation into an incompatible effect stack:
>>>:{coerceEs :: Eff es1 a -> Eff es2 a coerceEs = inject :} ... ...Couldn't match type ‘es1’ with ‘es2’ ...
class KnownPrefix es => Subset (subEs :: [Effect]) (es :: [Effect]) Source #
Provide evidence that subEs is a subset of es.
Instances
| (KnownPrefix es, IsUnknownSuffixOf subEs es) => Subset subEs es Source # | |
Defined in Effectful.Internal.Effect | |
| KnownPrefix es => Subset ('[] :: [Effect]) es Source # | |
Defined in Effectful.Internal.Effect | |
| (e :> es, Subset subEs es) => Subset (e ': subEs) es Source # | |
Defined in Effectful.Internal.Effect | |
Unlifting
data UnliftStrategy Source #
The strategy to use when unlifting Eff computations via
withEffToIO or the localUnlift
family.
Constructors
| SeqUnlift | The sequential strategy is the fastest and a default setting for
|
| SeqForkUnlift | Like The main consequence is that thread local state is forked at the point of creation of the unlifting function and its modifications in unlifted actions will not affect the main thread of execution (and vice versa):
Because of this it's possible to safely use the unlifting function outside
of the scope of effects it captures, e.g. by creating an
This doesn't work with the
However, it does with the
|
| ConcUnlift !Persistence !Limit | The concurrent strategy makes it possible for the unlifting function to
be called in threads distinct from its creator. See |
Instances
data Persistence Source #
Persistence setting for the ConcUnlift strategy.
Different functions require different persistence strategies. Examples:
- Lifting
pooledMapConcurrentlyNfrom theunliftiolibrary requires theEphemeralstrategy as we don't want jobs to share environment changes made by previous jobs run in the same worker thread. - Lifting
forkIOWithUnmaskrequires thePersistentstrategy, otherwise the unmasking function would start with a fresh environment each time it's called.
Both cases come down to what happens when the unlifting function is called
more than once in the same thread. If a thread calls it only once, the
Persistence setting makes no observable difference.
Example 1
Consider a thread that modifies thread local state, then inspects it with a second call to the unlifting function:
>>>import Control.Concurrent>>>import Control.Monad>>>import Effectful>>>import Effectful.State.Dynamic
>>>:{modifyThenGet :: UnliftStrategy -> IO Int modifyThenGet strategy = runEff . evalStateLocal @Int 0 $ do withEffToIO strategy $ \unlift -> do result <- newEmptyMVar void . forkIO $ do unlift $ modify @Int (+1) putMVar result =<< unlift (get @Int) takeMVar result :}
With the Persistent strategy the unlifting function keeps the environment
between the calls, so the second call sees the modification from the first
one:
>>>modifyThenGet $ ConcUnlift Persistent (Limited 1)1
On the other hand, with Ephemeral each call to the unlifting function
starts with a fresh copy of the environment, so the modification is silently
lost:
>>>modifyThenGet $ ConcUnlift Ephemeral (Limited 2)0
This also showcases the limit meaning different things for the two settings:
for the Persistent strategy it limits the number of threads the unlifting
can happen in, for Ephemeral it limits the number of calls to the unlifting
function.
Example 2
Consider a situation where a single worker thread runs multiple independent jobs:
>>>:{twoJobs :: UnliftStrategy -> IO [Int] twoJobs strategy = runEff . evalStateLocal @Int 0 $ do withEffToIO strategy $ \unlift -> do result <- newEmptyMVar void . forkIO $ do let job = unlift $ modify @Int (+1) >> get @Int putMVar result =<< sequence [job, job] takeMVar result :}
With Ephemeral both jobs start from the environment as it was when the
unlifting function was created:
>>>twoJobs $ ConcUnlift Ephemeral Unlimited[1,1]
With Persistent the second job inherits changes made by the first one, even
though the user would most likely expect them to be independent:
>>>twoJobs $ ConcUnlift Persistent Unlimited[1,2]
Constructors
| Ephemeral | Don't persist the environment between calls to the unlifting function in threads distinct from its creator. |
| Persistent | Persist the environment between calls to the unlifting function within a particular thread. |
Instances
| Generic Persistence Source # | |
Defined in Effectful.Internal.Unlift Associated Types type Rep Persistence :: Type -> Type # | |
| Show Persistence Source # | |
Defined in Effectful.Internal.Unlift Methods showsPrec :: Int -> Persistence -> ShowS # show :: Persistence -> String # showList :: [Persistence] -> ShowS # | |
| Eq Persistence Source # | |
Defined in Effectful.Internal.Unlift | |
| Ord Persistence Source # | |
Defined in Effectful.Internal.Unlift Methods compare :: Persistence -> Persistence -> Ordering # (<) :: Persistence -> Persistence -> Bool # (<=) :: Persistence -> Persistence -> Bool # (>) :: Persistence -> Persistence -> Bool # (>=) :: Persistence -> Persistence -> Bool # max :: Persistence -> Persistence -> Persistence # min :: Persistence -> Persistence -> Persistence # | |
| type Rep Persistence Source # | |
Limit setting for the ConcUnlift strategy.
Constructors
| Limited !Int | Behavior dependent on the For For |
| Unlimited | Unlimited use of the unlifting function. |
Instances
| Generic Limit Source # | |
| Show Limit Source # | |
| Eq Limit Source # | |
| Ord Limit Source # | |
| type Rep Limit Source # | |
Defined in Effectful.Internal.Unlift type Rep Limit = D1 ('MetaData "Limit" "Effectful.Internal.Unlift" "effectful-core-2.7.1.1-inplace" 'False) (C1 ('MetaCons "Limited" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Int)) :+: C1 ('MetaCons "Unlimited" 'PrefixI 'False) (U1 :: Type -> Type)) | |
unliftStrategy :: (HasCallStack, IOE :> es) => Eff es UnliftStrategy Source #
Get the current UnliftStrategy.
Note: this strategy is implicitly used by the MonadUnliftIO and
MonadBaseControl instance for Eff.
withUnliftStrategy :: (HasCallStack, IOE :> es) => UnliftStrategy -> Eff es a -> Eff es a Source #
Locally override the current UnliftStrategy with the given value.
Arguments
| :: (HasCallStack, IOE :> es) | |
| => ((forall r. Eff es r -> IO r) -> IO a) | Continuation with the unlifting function in scope. |
| -> Eff es a |
Create an unlifting function with the SeqUnlift strategy. For the general
version see withEffToIO.
Note: usage of this function is preferrable to withRunInIO
because of explicit unlifting strategy and better error reporting.
Since: 2.2.2.0
Arguments
| :: (HasCallStack, IOE :> es) | |
| => UnliftStrategy | |
| -> ((forall r. Eff es r -> IO r) -> IO a) | Continuation with the unlifting function in scope. |
| -> Eff es a |
Create an unlifting function with the given strategy.
Note: usage of this function is preferrable to withRunInIO
because of explicit unlifting strategy and better error reporting.
reallyUnsafeLiftMapIO :: (IO a -> IO b) -> Eff es a -> Eff es b Source #
Utility for lifting IO computations of type
IOa ->IOb
to
Effes a ->Effes b
This function is really unsafe because:
- It can be used to introduce arbitrary
IOactions into pureEffcomputations. - The
IOcomputation must run its argument in a way that's perceived as sequential to the outside observer, e.g. in the same thread or in a worker thread that finishes before the argument is run again.
Warning: if you disregard the second point, you will experience weird bugs, data races or internal consistency check failures.
When in doubt, use unsafeLiftMapIO, especially
since this version saves only a simple safety check per call of
reallyUnsafeLiftMapIO f.
reallyUnsafeUnliftIO :: ((forall r. Eff es r -> IO r) -> IO a) -> Eff es a Source #
Create an unlifting function.
This function is really unsafe because:
- It can be used to introduce arbitrary
IOactions into pureEffcomputations. - Unlifted
Effcomputations must be run in a way that's perceived as sequential to the outside observer, e.g. in the same thread as the caller ofreallyUnsafeUnliftIOor in a worker thread that finishes before another unlifted computation is run.
Warning: if you disregard the second point, you will experience weird bugs, data races or internal consistency check failures.
When in doubt, use unsafeSeqUnliftIO, especially
since this version saves only a simple safety check per call of the unlifting
function.
Low-level unlifts
Arguments
| :: HasCallStack | |
| => Env es | The environment. |
| -> ((forall r. Eff es r -> IO r) -> IO a) | Continuation with the unlifting function in scope. |
| -> IO a |
Create an unlifting function with the SeqUnlift strategy.
Arguments
| :: HasCallStack | |
| => Env es | The environment. |
| -> ((forall r. Eff es r -> IO r) -> IO a) | Continuation with the unlifting function in scope. |
| -> IO a |
Create an unlifting function with the SeqForkUnlift strategy.
Arguments
| :: HasCallStack | |
| => Env es | The environment. |
| -> Persistence | |
| -> Limit | |
| -> ((forall r. Eff es r -> IO r) -> IO a) | Continuation with the unlifting function in scope. |
| -> IO a |
Create an unlifting function with the ConcUnlift strategy.
Arguments
| :: HasCallStack | |
| => Env es | |
| -> Env localEs | |
| -> ((forall r. Eff es r -> IO r) -> (forall r. Eff localEs r -> IO r) -> IO a) | Continuation with the unlifting functions in scope. |
| -> IO a |
Create two unlifting functions with the SeqForkUnlift strategy.
The unlifting functions will share the effect storage (unlike with two
separate calls to seqForkUnliftIO).
Warning: both environments must have the same underlying storage.
Since: 2.7.0.0
Arguments
| :: HasCallStack | |
| => Env es | |
| -> Env localEs | The environment. |
| -> Persistence | |
| -> Limit | |
| -> ((forall r. Eff es r -> IO r) -> (forall r. Eff localEs r -> IO r) -> IO a) | Continuation with the unlifting functions in scope. |
| -> IO a |
Create unlifting functions with the ConcUnlift strategy.
In the Persistent variant the unlifting functions will share the effect
storage in each thread (unlike with two separate calls to concUnliftIO).
Warning: both environments must have the same underlying storage.
Since: 2.7.0.0
Dispatch
Dynamic dispatch
type EffectHandler (e :: Effect) (es :: [Effect]) Source #
Arguments
| = forall a localEs. (HasCallStack, e :> localEs) | |
| => LocalEnv localEs | Capture of the local environment for handling local |
| -> e (Eff localEs) a | The operation. |
| -> Eff es a |
Type signature of the effect handler.
unwrapLocalEnv :: HasCallStack => Env es -> LocalEnv localEs -> IO (Env localEs) Source #
Unwrap the LocalEnv via requireMatchingStorages.
requireMatchingStorages :: HasCallStack => Env es -> LocalEnv localEs -> IO () Source #
Make sure that the LocalEnv is used in the thread/context of the effect
handler it belongs to.
data Handler :: Effect -> Type where Source #
An internal representation of dynamically dispatched effects, i.e. the effect handler bundled with its environment.
Constructors
| Handler :: !(Env handlerEs) -> !(HandlerImpl e handlerEs) -> Handler e |
newtype HandlerImpl e es Source #
Wrapper to prevent a space leak on reconstruction of Handler in
relinkHandler (see https://gitlab.haskell.org/ghc/ghc/-/issues/25520).
Constructors
| HandlerImpl (EffectHandler e es) |
relinkHandler :: Relinker Handler e Source #
runHandler :: (HasCallStack, DispatchOf e ~ Dynamic) => Handler e -> Eff (e : es) a -> Eff es a Source #
Run a dynamically dispatched effect with the given handler.
Arguments
| :: (HasCallStack, DispatchOf e ~ Dynamic, e :> es) | |
| => e (Eff es) a | The operation. |
| -> Eff es a |
Send an operation of the given effect to its handler for execution.
Static dispatch
data family StaticRep (e :: Effect) :: Type Source #
Internal representations of statically dispatched effects.
Instances
type family MaybeIOE (sideEffects :: SideEffects) (es :: [Effect]) :: Constraint where ... Source #
Require the IOE effect for running statically dispatched effects whose
operations perform side effects.
Equations
| MaybeIOE NoSideEffects _ = () | |
| MaybeIOE WithSideEffects es = IOE :> es |
Arguments
| :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) | |
| => StaticRep e | The initial representation. |
| -> Eff (e : es) a | |
| -> Eff es (a, StaticRep e) |
Run a statically dispatched effect with the given initial representation and return the final value along with the final representation.
Arguments
| :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) | |
| => StaticRep e | The initial representation. |
| -> Eff (e : es) a | |
| -> Eff es a |
Run a statically dispatched effect with the given initial representation and return the final value, discarding the final representation.
Arguments
| :: (HasCallStack, DispatchOf e ~ Static sideEffects, MaybeIOE sideEffects es) | |
| => StaticRep e | The initial representation. |
| -> Eff (e : es) a | |
| -> Eff es (StaticRep e) |
Run a statically dispatched effect with the given initial representation and return the final representation, discarding the final value.
getStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => Eff es (StaticRep e) Source #
Fetch the current representation of the effect.
putStaticRep :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) => StaticRep e -> Eff es () Source #
Set the current representation of the effect to the given value.
Arguments
| :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) | |
| => (StaticRep e -> (a, StaticRep e)) | The function to modify the representation. |
| -> Eff es a |
Apply the function to the current representation of the effect and return a value.
Arguments
| :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) | |
| => (StaticRep e -> Eff es (a, StaticRep e)) | The function to modify the representation. |
| -> Eff es a |
Apply the monadic function to the current representation of the effect and return a value.
Arguments
| :: (HasCallStack, DispatchOf e ~ Static sideEffects, e :> es) | |
| => (StaticRep e -> StaticRep e) | The function to temporarily modify the representation. |
| -> Eff es a | |
| -> Eff es a |
Execute a computation with a temporarily modified representation of the effect.