| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Control.Effect.Writer
Contents
Synopsis
- data Tell s m a where
- data Listen s m a where
- data Pass s m a where
- type Writer s = Bundle '[Tell s, Listen s, Pass s]
- tell :: Eff (Tell s) m => s -> m ()
- listen :: Eff (Listen s) m => m a -> m (s, a)
- pass :: Eff (Pass s) m => m (s -> s, a) -> m a
- censor :: Eff (Pass s) m => (s -> s) -> m a -> m a
- runTell :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => TellC s m a -> m (s, a)
- runTellLazy :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterLazyThreads] m p) => TellLazyC s m a -> m (s, a)
- runTellList :: forall s m a p. (Carrier m, Threaders '[WriterThreads] m p) => TellListC s m a -> m ([s], a)
- runTellListLazy :: forall s m a p. (Carrier m, Threaders '[WriterLazyThreads] m p) => TellListLazyC s m a -> m ([s], a)
- tellToIO :: forall s m a. (Monoid s, Eff (Embed IO) m) => InterpretReifiedC (Tell s) m a -> m (s, a)
- runTellIORef :: forall s m a. (Monoid s, Eff (Embed IO) m) => IORef s -> InterpretReifiedC (Tell s) m a -> m a
- runTellTVar :: forall s m a. (Monoid s, Eff (Embed IO) m) => TVar s -> InterpretReifiedC (Tell s) m a -> m a
- tellIntoEndoTell :: (Monoid s, HeadEff (Tell (Endo s)) m) => TellIntoEndoTellC s m a -> m a
- tellToTell :: forall s t m a. Eff (Tell t) m => (s -> t) -> InterpretReifiedC (Tell s) m a -> m a
- tellIntoTell :: forall s t m a. HeadEff (Tell t) m => (s -> t) -> ReinterpretReifiedC (Tell s) '[Tell t] m a -> m a
- tellToIOSimple :: forall s m a p. (Monoid s, Eff (Embed IO) m, Threaders '[ReaderThreads] m p) => InterpretSimpleC (Tell s) m a -> m (s, a)
- runTellIORefSimple :: forall s m a p. (Monoid s, Eff (Embed IO) m, Threaders '[ReaderThreads] m p) => IORef s -> InterpretSimpleC (Tell s) m a -> m a
- runTellTVarSimple :: forall s m a p. (Monoid s, Eff (Embed IO) m, Threaders '[ReaderThreads] m p) => TVar s -> InterpretSimpleC (Tell s) m a -> m a
- tellToTellSimple :: forall s t m a p. (Eff (Tell t) m, Threaders '[ReaderThreads] m p) => (s -> t) -> InterpretSimpleC (Tell s) m a -> m a
- tellIntoTellSimple :: forall s t m a p. (HeadEff (Tell t) m, Threaders '[ReaderThreads] m p) => (s -> t) -> ReinterpretSimpleC (Tell s) '[Tell t] m a -> m a
- runListen :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => ListenC s m a -> m (s, a)
- runListenLazy :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => ListenLazyC s m a -> m (s, a)
- listenToIO :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => ListenTVarC s m a -> m (s, a)
- runListenTVar :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => TVar s -> ListenTVarC s m a -> m a
- listenIntoEndoListen :: (Monoid s, HeadEffs '[Listen (Endo s), Tell (Endo s)] m) => ListenIntoEndoListenC s m a -> m a
- runWriter :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => WriterC s m a -> m (s, a)
- runWriterLazy :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterLazyThreads] m p) => WriterLazyC s m a -> m (s, a)
- writerToIO :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => WriterTVarC s m a -> m (s, a)
- runWriterTVar :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => TVar s -> WriterTVarC s m a -> m a
- writerToBracket :: forall s m a p. (Monoid s, Effs [Embed IO, Bracket] m, Threaders '[ReaderThreads] m p) => WriterToBracketC s m a -> m (s, a)
- writerToBracketTVar :: forall s m a p. (Monoid s, Effs [Embed IO, Bracket] m, Threaders '[ReaderThreads] m p) => TVar s -> WriterToBracketC s m a -> m a
- writerIntoEndoWriter :: (Monoid s, HeadEffs '[Pass (Endo s), Listen (Endo s), Tell (Endo s)] m) => WriterIntoEndoWriterC s m a -> m a
- fromEndoWriter :: (Monoid s, Functor f) => f (Endo s, a) -> f (s, a)
- class (forall s. Monoid s => Threads (WriterT s) p) => WriterThreads p
- class (forall s. Monoid s => Threads (WriterT s) p) => WriterLazyThreads p
- class MonadCatch m => MonadMask (m :: Type -> Type)
- data TellC s m a
- data TellLazyC s m a
- type TellListC s = CompositionC '[ReinterpretC TellListH (Tell s) '[Tell (Dual [s])], TellC (Dual [s])]
- type TellListLazyC s = CompositionC '[ReinterpretC TellListLazyH (Tell s) '[Tell (Endo [s])], TellLazyC (Endo [s])]
- type TellIntoEndoTellC s = ReinterpretC WriterToEndoWriterH (Tell s) '[Tell (Endo s)]
- data ListenC s m a
- data ListenLazyC s m a
- type ListenTVarC s = CompositionC '[IntroC '[Listen s, Tell s] '[ListenPrim s, Local (s -> STM ()), Ask (s -> STM ())], InterpretC WriterTVarH (Listen s), InterpretC WriterTVarH (Tell s), InterpretPrimC WriterTVarH (ListenPrim s), ReaderC (s -> STM ())]
- type ListenIntoEndoListenC s = CompositionC '[IntroC '[Listen s, Tell s] '[Listen (Endo s), Tell (Endo s)], InterpretC WriterToEndoWriterH (Listen s), InterpretC WriterToEndoWriterH (Tell s)]
- data WriterC s m a
- data WriterLazyC s m a
- type WriterTVarC s = CompositionC '[IntroC '[Pass s, Listen s, Tell s] '[ListenPrim s, WriterPrim s, Local (s -> STM ()), Ask (s -> STM ())], InterpretC WriterTVarH (Pass s), InterpretC WriterTVarH (Listen s), InterpretC WriterTVarH (Tell s), InterpretC WriterTVarH (ListenPrim s), InterpretPrimC WriterTVarH (WriterPrim s), ReaderC (s -> STM ())]
- type WriterToBracketC s = CompositionC '[IntroC '[Pass s, Listen s, Tell s] '[Local (s -> STM ()), Ask (s -> STM ())], InterpretC WriterToBracketH (Pass s), InterpretC WriterToBracketH (Listen s), InterpretC WriterTVarH (Tell s), ReaderC (s -> STM ())]
- type WriterIntoEndoWriterC s = CompositionC '[IntroC '[Pass s, Listen s, Tell s] '[Pass (Endo s), Listen (Endo s), Tell (Endo s)], InterpretC WriterToEndoWriterH (Pass s), InterpretC WriterToEndoWriterH (Listen s), InterpretC WriterToEndoWriterH (Tell s)]
Effects
data Tell s m a where Source #
An effect for arbitrary output.
Instances
| (Monoid w, Carrier m, Threaders (SteppedThreads ': ([] :: [[Effect] -> Constraint])) m p) => PrimHandler ListenSteppedH (ListenPrim w) (SteppedC (Tell w :: (Type -> Type) -> Type -> Type) m) Source # | |
Defined in Control.Effect.Internal.Intercept Methods effPrimHandler :: EffPrimHandler (ListenPrim w) (SteppedC (Tell w) m) Source # | |
data Listen s m a where Source #
An effect for hearing what a computation
has to tell.
Instances
| Eff (ListenPrim w) m => Handler ListenSteppedH (Listen w) m Source # | |
Defined in Control.Effect.Internal.Intercept Methods effHandler :: EffHandler (Listen w) m Source # | |
Actions
Interpretations for Tell
runTell :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => TellC s m a -> m (s, a) Source #
Run a effect, where Tell ss is a Monoid, by accumulating
all the uses of tell.
You may want to combine this with tellIntoTell.
Unlike runListen and runWriter, this does not provide the ability to
interact with the tells through listen and pass; but also doesn't
impose any primitive effects, meaning runTell doesn't restrict what
interpreters are run before it.
Derivs(TellCs m) =Tells ':Derivsm
Prims(TellCs m) =Primsm
This produces the final accumulation s strictly. See runTellLazy for a
lazy variant of this.
runTellLazy :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterLazyThreads] m p) => TellLazyC s m a -> m (s, a) Source #
Run a effect, where Tell ss is a Monoid, by accumulating all the
uses of tell lazily.
Derivs(TellLazyCs m) =Tells ':Derivsm
Prims(TellLazyCs m) =Primsm
This is a variant of runTell that produces the final accumulation
lazily. Use this only if you need
the laziness, as this would otherwise incur an unneccesary space leak.
runTellList :: forall s m a p. (Carrier m, Threaders '[WriterThreads] m p) => TellListC s m a -> m ([s], a) Source #
Run a by gathering the Tell stells into a list.
The resulting list is produced strictly. See runTellListLazy for a lazy
variant.
runTellListLazy :: forall s m a p. (Carrier m, Threaders '[WriterLazyThreads] m p) => TellListLazyC s m a -> m ([s], a) Source #
Run a by gathering the Tell stells into a list.
This is a variant of runTellList that produces the
final list lazily. Use this only if you need
the laziness, as this would otherwise incur an unneccesary space leak.
tellToIO :: forall s m a. (Monoid s, Eff (Embed IO) m) => InterpretReifiedC (Tell s) m a -> m (s, a) Source #
Run a effect where Tell ss is a Monoid by accumulating uses of
tell through atomic operations in IO.
You may want to combine this with tellIntoTell.
This has a higher-rank type, as it makes use of InterpretReifiedC.
This makes tellToIO very difficult to use partially applied.
In particular, it can't be composed using ..
If performance is secondary, consider using the slower
tellToIOSimple, which doesn't have a higher-rank type.
runTellIORef :: forall s m a. (Monoid s, Eff (Embed IO) m) => IORef s -> InterpretReifiedC (Tell s) m a -> m a Source #
Run a effect where Tell ss is a Monoid by accumulating uses of
tell through using atomic operations in IO over the provided IORef.
This has a higher-rank type, as it makes use of InterpretReifiedC.
This makes runTellIORef very difficult to use partially applied.
In particular, it can't be composed using ..
If performance is secondary, consider using the slower
runTellIORefSimple, which doesn't have a higher-rank type.
runTellTVar :: forall s m a. (Monoid s, Eff (Embed IO) m) => TVar s -> InterpretReifiedC (Tell s) m a -> m a Source #
Run a effect where Tell ss is a Monoid by accumulating uses of
tell through using atomic operations in IO over the provided TVar.
This has a higher-rank type, as it makes use of InterpretReifiedC.
This makes runTellTVar very difficult to use partially applied.
In particular, it can't be composed using ..
If performance is secondary, consider using the slower
runTellTVarSimple, which doesn't have a higher-rank type.
tellIntoEndoTell :: (Monoid s, HeadEff (Tell (Endo s)) m) => TellIntoEndoTellC s m a -> m a Source #
Rewrite a effect into a Tell s effect.Tell (Endo s)
This effectively right-associates all uses of tell, which
asymptotically improves performance if the time complexity of <> for the
Monoid depends only on the size of the first argument.
In particular, you should use this (if you can be bothered) if the monoid
is a list, such as String.
Usage is to combine this with the Tell interpreter of your choice, followed
by fromEndoWriter, like this:
run$ ... $fromEndoWriter$runTell$tellIntoEndoTell@String -- TheMonoidmust be specified $ ...
tellToTell :: forall s t m a. Eff (Tell t) m => (s -> t) -> InterpretReifiedC (Tell s) m a -> m a Source #
Transform a Tell effect into another Tell effect by providing a function
to transform the type told.
This is useful to transform a effect where Tell ss isn't a Monoid
into a effect where @@ _is_ a Tell tMonoid, and thus can be
interpreted using the various Monoidal Tell interpreters.
This has a higher-rank type, as it makes use of InterpretReifiedC.
This makes tellToTell very difficult to use partially applied.
In particular, it can't be composed using ..
If performance is secondary, consider using the slower
tellToTellSimple, which doesn't have a higher-rank type.
tellIntoTell :: forall s t m a. HeadEff (Tell t) m => (s -> t) -> ReinterpretReifiedC (Tell s) '[Tell t] m a -> m a Source #
Rewrite a Tell effect into another Tell effect on top of the effect
stack by providing a function to transform the type told.
This is useful to rewrite a effect where Tell ss isn't a Monoid
into a effect where Tell tt _is_ a Monoid, and thus can be
interpreted using the various Monoidal Tell interpreters.
This has a higher-rank type, as it makes use of InterpretReifiedC.
This makes tellToTell very difficult to use partially applied.
In particular, it can't be composed using ..
If performance is secondary, consider using the slower
tellIntoTellSimple, which doesn't have a higher-rank type.
Simple variants of interpretations for Tell
tellToIOSimple :: forall s m a p. (Monoid s, Eff (Embed IO) m, Threaders '[ReaderThreads] m p) => InterpretSimpleC (Tell s) m a -> m (s, a) Source #
runTellIORefSimple :: forall s m a p. (Monoid s, Eff (Embed IO) m, Threaders '[ReaderThreads] m p) => IORef s -> InterpretSimpleC (Tell s) m a -> m a Source #
runTellTVarSimple :: forall s m a p. (Monoid s, Eff (Embed IO) m, Threaders '[ReaderThreads] m p) => TVar s -> InterpretSimpleC (Tell s) m a -> m a Source #
tellToTellSimple :: forall s t m a p. (Eff (Tell t) m, Threaders '[ReaderThreads] m p) => (s -> t) -> InterpretSimpleC (Tell s) m a -> m a Source #
Transform a Tell effect into another Tell effect by providing a function
to transform the type told.
This is useful to transform a where Tell ss isn't a Monoid into a
effect where @@ _is_ a Tell tMonoid, and thus can be interpreted using
the various Monoidal Tell interpreters.
This is a less performant version of tellToTell that doesn't have
a higher-rank type, making it much easier to use partially applied.
tellIntoTellSimple :: forall s t m a p. (HeadEff (Tell t) m, Threaders '[ReaderThreads] m p) => (s -> t) -> ReinterpretSimpleC (Tell s) '[Tell t] m a -> m a Source #
Rewrite a Tell effect into another Tell effect on top of the effect
stack by providing a function to transform the type told.
This is useful to rewrite a effect where Tell ss isn't a Monoid
into a effect where @@ _is_ a Tell tMonoid, and thus can be
interpreted using the various Monoidal Tell interpreters.
This has a higher-rank type, as it makes use of InterpretReifiedC.
This makes tellToTell very difficult to use partially applied.
In particular, it can't be composed using ..
If performance is secondary, consider using the slower
tellIntoTellSimple, which doesn't have a higher-rank type.
This is a less performant version of tellIntoTell that doesn't have
a higher-rank type, making it much easier to use partially applied.
Interpretations for Tell + Listen
runListen :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => ListenC s m a -> m (s, a) Source #
Run connected and Listen s effects, where Tell ss is a Monoid,
by accumulating all the uses of tell.
Unlike runWriter, this does not provide the power of pass; but because
of that, it also doesn't impose Pass as a primitive effect, meaning
a larger variety of interpreters may be run before runListen compared to
runWriter.
Derivs(ListenCs m) =Listens ':Tells ':Derivsm
Prims(ListenCs m) =ListenPrims ':Primsm
This produces the final accumulation strictly. See runListenLazy for a
lazy variant of this.
runListenLazy :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => ListenLazyC s m a -> m (s, a) Source #
Run connected and Listen s effects,
where Tell ss is a Monoid, by accumulating all the uses of tell lazily.
Derivs(ListenLazyCs m) =Listens ':Tells ':Derivsm
Prims(ListenLazyCs m) =ListenPrims ':Primsm
This is a variant of runListen that produces the
final accumulation lazily. Use this only if you need
the laziness, as this would otherwise incur an unneccesary space leak.
listenToIO :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => ListenTVarC s m a -> m (s, a) Source #
Run connected and Listen s effects by accumulating uses of
Tell stell through using atomic operations in IO.
Derivs(ListenTVarCs m) =Listens ':Tells ':Derivsm
Prims(ListenTVarCs m) =ListenPrims ':ReaderPrim(s -> STM ()) ':Primsm
Note that unlike tellToIO, this does not have a higher-rank type.
runListenTVar :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => TVar s -> ListenTVarC s m a -> m a Source #
Run connected and Listen s effects by accumulating uses of
Tell stell through using atomic operations in IO over the provided TVar.
Derivs(ListenTVarCs m) =Listens :Tells ':Derivsm
Prims(ListenTVarCs m) =ListenPrims ':ReaderPrim(s -> STM ()) ':Primsm
Note that unlike runTellTVar, this does not have a higher-rank type.
listenIntoEndoListen :: (Monoid s, HeadEffs '[Listen (Endo s), Tell (Endo s)] m) => ListenIntoEndoListenC s m a -> m a Source #
Rewrite connected and Listen s effects into
connected Tell s and Listen (Endo s) effects.Tell (Endo s)
This effectively right-associates all uses of tell, which
asymptotically improves performance if the time complexity of <> for the
Monoid depends only on the size of the first argument.
In particular, you should use this (if you can be bothered) if the monoid
is a list, such as String.
Usage is to combine this with the Listen interpreter of your choice,
followed by fromEndoWriter, like this:
run$ ... $fromEndoWriter$runListen$listenIntoEndoListen@String -- TheMonoidmust be specified $ ...
Interpretations for Writer (Tell + Listen + Pass)
runWriter :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterThreads] m p) => WriterC s m a -> m (s, a) Source #
Run connected , Pass s and Listen s effects,
-- i.e. Tell s -- where Writer ss is a Monoid, by accumulating all the
uses of tell.
is a fairly restrictive primitive effect. Notably,
Pass srunCont can't be used before runWriter.
If you don't need pass, consider using runTell or runListen instead.
Derivs(WriterCs m) =Passs ':Listens ':Tells ':Derivsm
Prims(WriterCs m) =WriterPrims ':Primsm
This produces the final accumulation strictly. See runWriterLazy for a
lazy variant of this.
runWriterLazy :: forall s m a p. (Monoid s, Carrier m, Threaders '[WriterLazyThreads] m p) => WriterLazyC s m a -> m (s, a) Source #
Run connected , Pass s and Listen s effects,
-- i.e. Tell s -- where Writer ss is a Monoid,
by accumulating all the uses of tell lazily.
Derivs(ListenLazyCs m) =Passs ':Listens ':Tells ':Derivsm
Prims(ListenLazyCs m) =WriterPrims ':Primsm
This is a variant of runListen that produces the
final accumulation lazily. Use this only if you need
the laziness, as this would otherwise incur an unneccesary space leak.
writerToIO :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => WriterTVarC s m a -> m (s, a) Source #
Run connected , Pass s and Listen s effects
-- i.e. Tell s -- by accumulating uses of Writer stell through using atomic
operations in IO.
Derivs(WriterTVarCs m) =Passs ':Listens :Tells ':Derivsm
Prims(WriterTVarCs m) =WriterPrims ':ReaderPrim(s -> STM ()) ':Primsm
Note that unlike tellToIO, this does not have a higher-rank type.
runWriterTVar :: forall s m a p. (Monoid s, Eff (Embed IO) m, MonadMask m, Threaders '[ReaderThreads] m p) => TVar s -> WriterTVarC s m a -> m a Source #
Run connected , Pass s and Listen s effects
-- i.e. Tell s -- by accumulating uses of Writer stell through using atomic
operations in IO over a TVar.
Derivs(WriterTVarCs m) =Passs ':Listens :Tells ':Derivsm
Prims(WriterTVarCs m) =WriterPrims ':ReaderPrim(s -> STM ()) ':Primsm
Note that unlike runTellTVar, this does not have a higher-rank type.
writerToBracket :: forall s m a p. (Monoid s, Effs [Embed IO, Bracket] m, Threaders '[ReaderThreads] m p) => WriterToBracketC s m a -> m (s, a) Source #
Run connected , Pass s and Listen s effects
-- i.e. Tell s -- by accumulating uses of Writer stell through using atomic
operations in IO, relying on the provided protection of Bracket for
the implementation.
Derivs(WriterToBracketCs m) =Passs ':Listens :Tells ':Derivsm
Prims(WriterToBracketCs m) =ReaderPrim(s -> STM ()) ':Primsm
Note that unlike writerToIO, this does not have a higher-rank type.
writerToBracketTVar :: forall s m a p. (Monoid s, Effs [Embed IO, Bracket] m, Threaders '[ReaderThreads] m p) => TVar s -> WriterToBracketC s m a -> m a Source #
Run connected , Pass s and Listen s effects
-- i.e. Tell s -- by accumulating uses of Writer stell through using atomic
operations in IO over a TVar, relying on the provided protection
of Bracket for the implementation.
Derivs(WriterToBracketCs m) =Passs ':Listens :Tells ':Derivsm
Prims(WriterToBracketCs m) =ReaderPrim(s -> STM ()) ':Primsm
Note that unlike runTellTVar, this does not have a higher-rank type.
writerIntoEndoWriter :: (Monoid s, HeadEffs '[Pass (Endo s), Listen (Endo s), Tell (Endo s)] m) => WriterIntoEndoWriterC s m a -> m a Source #
Rewrite connected , Pass s and Listen s effects
-- i.e. Tell s -- into connected Writer s,
Pass (Endo s) and Listen (Endo s) effects on top of the effect
stack -- i.e. Tell (Endo s).Writer (Endo s)
This effectively right-associates all uses of tell, which
asymptotically improves performance if the time complexity of <> for the
Monoid depends only on the size of the first argument.
In particular, you should use this (if you can be bothered) if the
monoid is a list, such as String.
Usage is to combine this with the Writer interpreter of your choice,
followed by fromEndoWriter, like this:
run$ ... $fromEndoWriter$runWriter$writerIntoEndoWriter@String -- TheMonoidmust be specified $ ...
Other utilities
Threading constraints
class (forall s. Monoid s => Threads (WriterT s) p) => WriterThreads p Source #
WriterThreads accepts the following primitive effects:
RegionalsOptionals(whensis a functor)BaseControlbListenPrims(whensis aMonoid)WriterPrims(whensis aMonoid)ReaderPrimiMaskBracketFixSplit
Instances
| (forall s. Monoid s => Threads (WriterT s) p) => WriterThreads p Source # | |
Defined in Control.Effect.Internal.Writer | |
class (forall s. Monoid s => Threads (WriterT s) p) => WriterLazyThreads p Source #
WriterLazyThreads accepts the following primitive effects:
RegionalsOptionals(whensis a functor)BaseControlbListenPrims(whensis aMonoid)WriterPrims(whensis aMonoid)ReaderPrimiMaskBracketFixSplit
Instances
| (forall s. Monoid s => Threads (WriterT s) p) => WriterLazyThreads p Source # | |
Defined in Control.Effect.Internal.Writer | |
MonadMask
class MonadCatch m => MonadMask (m :: Type -> Type) #
A class for monads which provide for the ability to account for all possible exit points from a computation, and to mask asynchronous exceptions. Continuation-based monads are invalid instances of this class.
Instances should ensure that, in the following code:
fg = f `finally` g
The action g is called regardless of what occurs within f, including
async exceptions. Some monads allow f to abort the computation via other
effects than throwing an exception. For simplicity, we will consider aborting
and throwing an exception to be two forms of "throwing an error".
If f and g both throw an error, the error thrown by fg depends on which
errors we're talking about. In a monad transformer stack, the deeper layers
override the effects of the inner layers; for example, ExceptT e1 (Except
e2) a represents a value of type Either e2 (Either e1 a), so throwing both
an e1 and an e2 will result in Left e2. If f and g both throw an
error from the same layer, instances should ensure that the error from g
wins.
Effects other than throwing an error are also overriden by the deeper layers.
For example, StateT s Maybe a represents a value of type s -> Maybe (a,
s), so if an error thrown from f causes this function to return Nothing,
any changes to the state which f also performed will be erased. As a
result, g will see the state as it was before f. Once g completes,
f's error will be rethrown, so g' state changes will be erased as well.
This is the normal interaction between effects in a monad transformer stack.
By contrast, lifted-base's
version of finally always discards all of g's non-IO effects, and g
never sees any of f's non-IO effects, regardless of the layer ordering and
regardless of whether f throws an error. This is not the result of
interacting effects, but a consequence of MonadBaseControl's approach.
Minimal complete definition
Instances
Carriers
Instances
Instances
type TellListC s = CompositionC '[ReinterpretC TellListH (Tell s) '[Tell (Dual [s])], TellC (Dual [s])] Source #
type TellListLazyC s = CompositionC '[ReinterpretC TellListLazyH (Tell s) '[Tell (Endo [s])], TellLazyC (Endo [s])] Source #
type TellIntoEndoTellC s = ReinterpretC WriterToEndoWriterH (Tell s) '[Tell (Endo s)] Source #
Instances
data ListenLazyC s m a Source #
Instances
type ListenTVarC s = CompositionC '[IntroC '[Listen s, Tell s] '[ListenPrim s, Local (s -> STM ()), Ask (s -> STM ())], InterpretC WriterTVarH (Listen s), InterpretC WriterTVarH (Tell s), InterpretPrimC WriterTVarH (ListenPrim s), ReaderC (s -> STM ())] Source #
type ListenIntoEndoListenC s = CompositionC '[IntroC '[Listen s, Tell s] '[Listen (Endo s), Tell (Endo s)], InterpretC WriterToEndoWriterH (Listen s), InterpretC WriterToEndoWriterH (Tell s)] Source #
Instances
data WriterLazyC s m a Source #
Instances
type WriterTVarC s = CompositionC '[IntroC '[Pass s, Listen s, Tell s] '[ListenPrim s, WriterPrim s, Local (s -> STM ()), Ask (s -> STM ())], InterpretC WriterTVarH (Pass s), InterpretC WriterTVarH (Listen s), InterpretC WriterTVarH (Tell s), InterpretC WriterTVarH (ListenPrim s), InterpretPrimC WriterTVarH (WriterPrim s), ReaderC (s -> STM ())] Source #
type WriterToBracketC s = CompositionC '[IntroC '[Pass s, Listen s, Tell s] '[Local (s -> STM ()), Ask (s -> STM ())], InterpretC WriterToBracketH (Pass s), InterpretC WriterToBracketH (Listen s), InterpretC WriterTVarH (Tell s), ReaderC (s -> STM ())] Source #
type WriterIntoEndoWriterC s = CompositionC '[IntroC '[Pass s, Listen s, Tell s] '[Pass (Endo s), Listen (Endo s), Tell (Endo s)], InterpretC WriterToEndoWriterH (Pass s), InterpretC WriterToEndoWriterH (Listen s), InterpretC WriterToEndoWriterH (Tell s)] Source #