general-allocate-0.2.3.1: Exception-safe resource management in more monads
CopyrightCopyright 2022 Shea Levy.
LicenseApache-2.0
Maintainershea@shealevy.com
Safe HaskellSafe-Inferred
LanguageHaskell2010

Control.Monad.With

Description

This module defines interfaces for safe resource usage on top of GeneralAllocate, where resource cleanup happens at the end of a lexical scope.

For contexts where nested scope-based allocation and release is insufficient, see Control.Monad.Allocate.

Synopsis

Documentation

class (Monad m, forall x y. Coercible x y => Coercible (m x) (m y)) => MonadWith m where Source #

A monad allowing for exception-safe resource usage within a lexical scope.

The guarantees of MonadWith are weaker than MonadMask: in some monads, it's possible for resources not to get cleaned up if the entire monadic computation is going to be aborted (e.g. an async exception sent to a thread executing a monad with no exception catching). Of course, MonadMask itself can't guarantee cleanup in the presence of SIGKILL... In any case, this allows for MonadWith to be implemented lawfully in more monads (see WithNoContinuation). In particular, the MonadWith instances for IO, ST, and Identity allow for writing monad-generic exception-safe code which can be properly instantiated in IO or mocked out in ST/Identity without changing the code.

Associated Types

type WithException m Source #

Data characterizing exceptional exit from the scope.

Methods

stateThreadingGeneralWith Source #

Arguments

:: GeneralAllocate m (WithException m) releaseReturn b a

Allocate the resource

-> (a -> m b)

Use the resource

-> m (b, releaseReturn) 

Allocate, use, and release a resource in some scope, threading through some state.

If resource acquisition succeeds, the resource is guaranteed to be released if the monadic computation itself is going to continue. This is weaker than the guarantees of generalBracket, which can't be implemented in monads without exception catching.

See generalWith for the common use case where state threading isn't needed.

Instances

Instances details
MonadWith Identity Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException Identity Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate Identity (WithException Identity) releaseReturn b a -> (a -> Identity b) -> Identity (b, releaseReturn) Source #

MonadWith IO Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException IO Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate IO (WithException IO) releaseReturn b a -> (a -> IO b) -> IO (b, releaseReturn) Source #

MonadWith (Either e) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (Either e) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (Either e) (WithException (Either e)) releaseReturn b a -> (a -> Either e b) -> Either e (b, releaseReturn) Source #

MonadWith (ST s) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (ST s) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (ST s) (WithException (ST s)) releaseReturn b a -> (a -> ST s b) -> ST s (b, releaseReturn) Source #

(Monad m, forall x y. Coercible x y => Coercible (m x) (m y)) => MonadWith (CatchT m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (CatchT m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (CatchT m) (WithException (CatchT m)) releaseReturn b a -> (a -> CatchT m b) -> CatchT m (b, releaseReturn) Source #

(Monad m, forall x y. Coercible x y => Coercible (m x) (m y)) => MonadWith (WithNoContinuation m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (WithNoContinuation m) Source #

MonadWith m => MonadWith (ResourceT m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (ResourceT m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (ResourceT m) (WithException (ResourceT m)) releaseReturn b a -> (a -> ResourceT m b) -> ResourceT m (b, releaseReturn) Source #

MonadWith m => MonadWith (MaybeT m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (MaybeT m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (MaybeT m) (WithException (MaybeT m)) releaseReturn b a -> (a -> MaybeT m b) -> MaybeT m (b, releaseReturn) Source #

MonadWith m => MonadWith (ExceptT e m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (ExceptT e m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (ExceptT e m) (WithException (ExceptT e m)) releaseReturn b a -> (a -> ExceptT e m b) -> ExceptT e m (b, releaseReturn) Source #

MonadWith m => MonadWith (IdentityT m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (IdentityT m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (IdentityT m) (WithException (IdentityT m)) releaseReturn b a -> (a -> IdentityT m b) -> IdentityT m (b, releaseReturn) Source #

MonadWith m => MonadWith (ReaderT r m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (ReaderT r m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (ReaderT r m) (WithException (ReaderT r m)) releaseReturn b a -> (a -> ReaderT r m b) -> ReaderT r m (b, releaseReturn) Source #

MonadWith m => MonadWith (StateT s m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (StateT s m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (StateT s m) (WithException (StateT s m)) releaseReturn b a -> (a -> StateT s m b) -> StateT s m (b, releaseReturn) Source #

MonadWith m => MonadWith (StateT s m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (StateT s m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (StateT s m) (WithException (StateT s m)) releaseReturn b a -> (a -> StateT s m b) -> StateT s m (b, releaseReturn) Source #

(MonadWith m, Monoid w) => MonadWith (WriterT w m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (WriterT w m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (WriterT w m) (WithException (WriterT w m)) releaseReturn b a -> (a -> WriterT w m b) -> WriterT w m (b, releaseReturn) Source #

(MonadWith m, Monoid w) => MonadWith (WriterT w m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (WriterT w m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (WriterT w m) (WithException (WriterT w m)) releaseReturn b a -> (a -> WriterT w m b) -> WriterT w m (b, releaseReturn) Source #

(MonadWith m, Monoid w) => MonadWith (RWST r w s m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (RWST r w s m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (RWST r w s m) (WithException (RWST r w s m)) releaseReturn b a -> (a -> RWST r w s m b) -> RWST r w s m (b, releaseReturn) Source #

(MonadWith m, Monoid w) => MonadWith (RWST r w s m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (RWST r w s m) Source #

Methods

stateThreadingGeneralWith :: GeneralAllocate (RWST r w s m) (WithException (RWST r w s m)) releaseReturn b a -> (a -> RWST r w s m b) -> RWST r w s m (b, releaseReturn) Source #

type With m = GeneralAllocate m (WithException m) () Source #

Describe the allocation and release of a resource.

A specialization of GeneralAllocate for the most common case with MonadWith, see generalWith.

generalWith Source #

Arguments

:: MonadWith m 
=> With m b a

Allocate the resource

-> (a -> m b)

Use the resource

-> m b 

Allocate, use, and release a resource in some scope.

If resource acquisition succeeds, the resource is guaranteed to be released if the monadic computation itself is going to continue. This is weaker than the guarantees of generalBracket, which can't be implemented in monads without exception catching.

onFailure Source #

Arguments

:: MonadWith m 
=> m a

Main action

-> (WithException m -> m b)

Failure action

-> m a 

Run some action if the first action fails.

Exception propagation will continue after the failure action runs.

If failure occurs, the failure action is guaranteed to run if the monadic compuation itself is going to continue. This is weaker than the guranatess of onError, which can't be implemented in monads without exception catching.

generalFinally Source #

Arguments

:: MonadWith m 
=> m a

Main action

-> m b

Final action

-> m (a, b) 

Run some action after another one completes in an exception-safe manner.

The final action is guaranteed to run if the monadic compuation itself is going to continue. This is weaker than the guranatess of finally, which can't be implemented in monads without exception catching.

class (MonadWith m, Exceptable (WithException m)) => MonadWithExceptable m Source #

A MonadWith whose exception type can be projected into the Haskell exception hierarchy

Until https://gitlab.haskell.org/ghc/ghc/-/issues/16478 is fixed, you probably want to add {-# OPTIONS_GHC -Wno-simplifiable-class-constraints #-} to modules using this.

Instances

Instances details
(MonadWith m, Exceptable (WithException m)) => MonadWithExceptable m Source # 
Instance details

Defined in Control.Monad.With

newtype WithNoContinuation m a Source #

A helper for DerivingVia a MonadWith and MonadWithExceptable instance for any Monad.

Note that the derived instance is only valid if the monad satisfies the "no continuation" condition, i.e. that if execution of a computation exits a given lexical scope we are guaranteed that either all of the actions within that scope have executed or the entire monadic computation has been terminated.

The most common factors violating "no continuation" are call/cc and exception catching. A monad which allows exception throwing but not catching is not thereby disqualified, as any thrown exception will of necessity propagate until it terminates the entire monadic computation.

Constructors

WithNoContinuation (m a) 

Instances

Instances details
Applicative m => Applicative (WithNoContinuation m) Source # 
Instance details

Defined in Control.Monad.With

Functor m => Functor (WithNoContinuation m) Source # 
Instance details

Defined in Control.Monad.With

Methods

fmap :: (a -> b) -> WithNoContinuation m a -> WithNoContinuation m b #

(<$) :: a -> WithNoContinuation m b -> WithNoContinuation m a #

Monad m => Monad (WithNoContinuation m) Source # 
Instance details

Defined in Control.Monad.With

(Monad m, forall x y. Coercible x y => Coercible (m x) (m y)) => MonadWith (WithNoContinuation m) Source # 
Instance details

Defined in Control.Monad.With

Associated Types

type WithException (WithNoContinuation m) Source #

type WithException (WithNoContinuation m) Source # 
Instance details

Defined in Control.Monad.With