Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data Bracket :: Effect 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
- bracketToIOUnsafe :: (Carrier m, MonadMask m) => BracketToIOUnsafeC 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 BracketToIOUnsafeC = InterpretPrimC BracketToIOUnsafeH Bracket
- type BracketLocallyC = InterpretPrimC BracketLocallyH Bracket
- type IgnoreBracketC = InterpretC IgnoreBracketH Bracket
Effects
data Bracket :: Effect 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 Bracket
threadBracketViaClass
can help you with that.
The following threading constraints accept Bracket
:
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 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
).
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.
Any generalBracket
will have its cleanup action be executed
uninterruptibly masked.
This means that the cleanup action cannot, under any circumstance,
be interrupted by asynchronous exceptions.
Derivs
(BracketToIOC
m) =Bracket
':Derivs
m
Prims
(BracketToIOC
m) =Bracket
':Prims
m
bracketToIOUnsafe :: (Carrier m, MonadMask m) => BracketToIOUnsafeC 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.
Any generalBracket
will have its cleanup action
be executed interruptibly masked.
This means that the cleanup action can be interrupted by
asynchronous exceptions if the cleanup action executes
interruptible (blocking) operations,
such as putMVar
.
Derivs
(BracketToIOUnsafeC
m) =Bracket
':Derivs
m
Prims
(BracketToIOUnsafeC
m) =Bracket
':Prims
m
Since: 0.2.0.0
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
(BracketLocallyC
m) =Bracket
':Derivs
m
Prims
(BracketLocallyC
m) =Bracket
':Prims
m
ignoreBracket :: Carrier m => IgnoreBracketC m a -> m a Source #
Run a Bracket
effect by ignoring it, providing no protection at all.
Derivs
(IgnoreBracketC
m) =Bracket
':Derivs
m
Prims
(IgnoreBracketC
m) =Prims
m
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 Bracket
t
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.
Instances
Carriers
type BracketToIOC = InterpretPrimC BracketToIOH Bracket Source #
type BracketToIOUnsafeC = InterpretPrimC BracketToIOUnsafeH Bracket Source #
type BracketLocallyC = InterpretPrimC BracketLocallyH Bracket Source #
type IgnoreBracketC = InterpretC IgnoreBracketH Bracket Source #