| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Control.Effect.Bracket
Synopsis
- data Bracket m a where
- GeneralBracket :: m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> Bracket m (b, c)
- data ExitCase a
- generalBracket :: Eff Bracket m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
- bracket :: Eff Bracket m => m a -> (a -> m c) -> (a -> m b) -> m b
- bracket_ :: Eff Bracket m => m a -> m c -> m b -> m b
- bracketOnError :: Eff Bracket m => m a -> (a -> m c) -> (a -> m b) -> m b
- onError :: Eff Bracket m => m a -> m b -> m a
- finally :: Eff Bracket m => m a -> m b -> m a
- bracketToIO :: (Carrier m, MonadMask m) => BracketToIOC m a -> m a
- runBracketLocally :: Carrier m => BracketLocallyC m a -> m a
- ignoreBracket :: Carrier m => IgnoreBracketC m a -> m a
- threadBracketViaClass :: forall t m a. Monad m => (RepresentationalT t, forall b. MonadMask b => MonadMask (t b)) => (forall x. Bracket m x -> m x) -> Bracket (t m) a -> t m a
- class MonadCatch m => MonadMask (m :: Type -> Type)
- type BracketToIOC = InterpretPrimC BracketToIOH Bracket
- type BracketLocallyC = InterpretPrimC BracketLocallyH Bracket
- type IgnoreBracketC = InterpretC IgnoreBracketH Bracket
Effects
data Bracket m a where Source #
An effect for exception-safe acquisition and release of resources.
Bracket is typically used as a primitive effect.
If you define a Carrier that relies on a novel
non-trivial monad transformer t, then you need to make
a instance (if possible).
ThreadsEff t BracketthreadBracketViaClass can help you with that.
The following threading constraints accept Bracket:
Constructors
| GeneralBracket :: m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> Bracket m (b, c) |
Instances
| ThreadsEff (ExceptT e) Bracket Source # | |
| Monoid s => ThreadsEff (WriterT s) Bracket Source # | |
| ThreadsEff (StateT s) Bracket Source # | |
| ThreadsEff (ReaderT i) Bracket Source # | |
| ThreadsEff (StateT s) Bracket Source # | |
| Monoid s => ThreadsEff (WriterT s) Bracket Source # | |
| Monoid s => ThreadsEff (WriterT s) Bracket Source # | |
| Monad m => MonadThrow (ViaAlg s Bracket m) Source # | |
| Monad m => MonadCatch (ViaAlg s Bracket m) Source # | |
| (Reifies s (ReifiedEffAlgebra Bracket m), Monad m) => MonadMask (ViaAlg s Bracket m) Source # | |
Defined in Control.Effect.Type.Bracket Methods mask :: ((forall a. ViaAlg s Bracket m a -> ViaAlg s Bracket m a) -> ViaAlg s Bracket m b) -> ViaAlg s Bracket m b # uninterruptibleMask :: ((forall a. ViaAlg s Bracket m a -> ViaAlg s Bracket m a) -> ViaAlg s Bracket m b) -> ViaAlg s Bracket m b # generalBracket :: ViaAlg s Bracket m a -> (a -> ExitCase b -> ViaAlg s Bracket m c) -> (a -> ViaAlg s Bracket m b) -> ViaAlg s Bracket m (b, c) # | |
A MonadMask computation may either succeed with a value, abort with an
exception, or abort for some other reason. For example, in ExceptT e IO
you can use throwM to abort with an exception (ExitCaseException) or
throwE to abort with a value of type e
(ExitCaseAbort).
Constructors
| ExitCaseSuccess a | |
| ExitCaseException SomeException | |
| ExitCaseAbort |
Actions
generalBracket :: Eff Bracket m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c) Source #
bracketOnError :: Eff Bracket m => m a -> (a -> m c) -> (a -> m b) -> m b Source #
Interpretations
bracketToIO :: (Carrier m, MonadMask m) => BracketToIOC m a -> m a Source #
Run a Bracket by effect that protects against
any abortive computation of any effect, as well
as any IO exceptions and asynchronous exceptions.
Derivs(BracketToIOCm) =Bracket':Derivsm
Prims(BracketToIOCm) =Bracket':Primsm
runBracketLocally :: Carrier m => BracketLocallyC m a -> m a Source #
Run a Bracket effect that protects against
any abortive computations of purely local effects
-- i.e. effects interpreted before runBracketLocally
that are not interpreted in terms of the final monad
nor other effects interpreted after runBracketLocally.
This does not protect against IO exceptions of any kind, including asynchronous exceptions.
This is more situational compared to bracketToIO,
but can be useful. For an example, see the wiki.
Derivs(BracketLocallyCm) =Bracket':Derivsm
Prims(BracketLocallyCm) =Bracket':Primsm
ignoreBracket :: Carrier m => IgnoreBracketC m a -> m a Source #
Run a Bracket effect by ignoring it, providing no protection at all.
Derivs(IgnoreBracketCm) =Bracket':Derivsm
Prims(IgnoreBracketCm) =Primsm
Threading utilities
threadBracketViaClass :: forall t m a. Monad m => (RepresentationalT t, forall b. MonadMask b => MonadMask (t b)) => (forall x. Bracket m x -> m x) -> Bracket (t m) a -> t m a Source #
A valid definition of threadEff for a instance,
given that ThreadsEff t Brackett lifts .MonadMask
BEWARE: threadBracketViaClass is only safe if the implementation of
generalBracket for t m only makes use of generalBracket for m,
and no other methods of MonadThrow, MonadCatch, or MonadMask.
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
type BracketToIOC = InterpretPrimC BracketToIOH Bracket Source #
type BracketLocallyC = InterpretPrimC BracketLocallyH Bracket Source #
type IgnoreBracketC = InterpretC IgnoreBracketH Bracket Source #