in-other-words-0.2.0.0: A higher-order effect system where the sky's the limit

Control.Effect.Bracket

Synopsis

# 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 ThreadsEff t Bracket instance (if possible). threadBracketViaClass can help you with that.

The following threading constraints accept Bracket:

• ReaderThreads
• StateThreads
• StateLazyThreads
• ErrorThreads
• WriterThreads
• WriterLazyThreads

Constructors

 GeneralBracket :: m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> Bracket m (b, c)

#### Instances

Instances details

data ExitCase a #

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

#### Instances

Instances details
 Show a => Show (ExitCase a) Instance detailsDefined in Control.Monad.Catch MethodsshowsPrec :: Int -> ExitCase a -> ShowS #show :: ExitCase a -> String #showList :: [ExitCase a] -> ShowS #

# Actions

generalBracket :: Eff Bracket m => m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c) Source #

bracket :: Eff Bracket m => m a -> (a -> m c) -> (a -> m b) -> m b Source #

bracket_ :: Eff Bracket m => m a -> m c -> m b -> m b Source #

bracketOnError :: Eff Bracket m => m a -> (a -> m c) -> (a -> m b) -> m b Source #

onError :: Eff Bracket m => m a -> m b -> m a Source #

finally :: Eff Bracket m => m a -> m b -> m a 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

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 ThreadsEff t Bracket instance, given that 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.

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

Instances details

# Carriers

type IgnoreBracketC = InterpretC IgnoreBracketH Bracket Source #