chain-0.1.0.0

Safe HaskellNone
LanguageHaskell2010

Control.Monad.Chain

Contents

Synopsis

ResultT

data ResultT msg (err :: [*]) m a Source #

Instances

MonadState s m => MonadState s (ResultT msg err m) Source # 

Methods

get :: ResultT msg err m s #

put :: s -> ResultT msg err m () #

state :: (s -> (a, s)) -> ResultT msg err m a #

MonadReader env m => MonadReader env (ResultT msg err m) Source # 

Methods

ask :: ResultT msg err m env #

local :: (env -> env) -> ResultT msg err m a -> ResultT msg err m a #

reader :: (env -> a) -> ResultT msg err m a #

MonadTrans (ResultT msg err) Source # 

Methods

lift :: Monad m => m a -> ResultT msg err m a #

Monad m => Monad (ResultT msg err m) Source # 

Methods

(>>=) :: ResultT msg err m a -> (a -> ResultT msg err m b) -> ResultT msg err m b #

(>>) :: ResultT msg err m a -> ResultT msg err m b -> ResultT msg err m b #

return :: a -> ResultT msg err m a #

fail :: String -> ResultT msg err m a #

Functor m => Functor (ResultT msg err m) Source # 

Methods

fmap :: (a -> b) -> ResultT msg err m a -> ResultT msg err m b #

(<$) :: a -> ResultT msg err m b -> ResultT msg err m a #

Monad m => Applicative (ResultT msg err m) Source # 

Methods

pure :: a -> ResultT msg err m a #

(<*>) :: ResultT msg err m (a -> b) -> ResultT msg err m a -> ResultT msg err m b #

liftA2 :: (a -> b -> c) -> ResultT msg err m a -> ResultT msg err m b -> ResultT msg err m c #

(*>) :: ResultT msg err m a -> ResultT msg err m b -> ResultT msg err m b #

(<*) :: ResultT msg err m a -> ResultT msg err m b -> ResultT msg err m a #

MonadIO m => MonadIO (ResultT msg err m) Source # 

Methods

liftIO :: IO a -> ResultT msg err m a #

runResultT :: Monad m => ResultT msg '[] m a -> m a Source #

Escape from the ResultT monad.

The type signature of runResultT obliges the library user to deal with errors, with functions such as recover, recoverMany, etc.

Result

type Result e a = ResultT e a Identity Source #

runResult :: Result msg '[] a -> a Source #

Monadic Operations

abort Source #

Arguments

:: ('[e] :| err, Monad m) 
=> e

A symbolic value which describes why the computation would not be completed. This symbolic value is of a type inside the row of errors.

-> ResultT msg err m a 

Abort the current computation and raise an error to describe the reason

Similarly to, e.g. Nothing for Maybe, abort is a computation shortcut. The rest of the monadic computation is not executed, and the error is transmitted to the caller computation. Using the recover, recoverWhile or recoverMany functions to stop the chain.

achieve Source #

Arguments

:: Monad m 
=> msg

A description of the computation, to act as context in case of error.

-> ResultT msg err m a 
-> ResultT msg err m a 

Declaratively describe the purpose of a computation.

Using achieve in various places, it becomes possible, once an error is raised, to determine more easily its context. achieve has an operator counterpart: '(?)'. The former should be used to contextualise a do-block, whereas the latter can be prefered for monadic function calls.

achieve "try to get configuration" $ do
    f <- readParseFile "main" <?> "read main file"
    f' <- readParseFile "aux" <?> "read aux file"
    pure $ buildConfiguration f f'

These contextual messages are made available, in addition to the error, when using functions such as recover, recoverMany, repeatUntil etc.

(<?>) :: Monad m => ResultT msg err m a -> msg -> ResultT msg err m a Source #

See achieve.

finally Source #

Arguments

:: Monad m 
=> ResultT msg err m a

The try block

-> ResultT msg err m ()

The finally block

-> ResultT msg err m a 

Always execute a given computation (called finally block thereafter) after a first computation (try block) has been completed.

The finally block is executed even if the try block is aborted. This allows to deal with clean-up code that has to be executed no matter what happened.

recover Source #

Arguments

:: Monad m 
=> ResultT msg (e ': err) m a

The try block

-> (e -> [msg] -> ResultT msg err m a)

The error handler

-> ResultT msg err m a 

Temporally allows one given error type by providing an error handler to execute in case of failure.

recoverWhile :: forall e m msg err a. Monad m => msg -> ResultT msg (e ': err) m a -> (e -> [msg] -> ResultT msg err m a) -> ResultT msg err m a Source #

Combine recover and achieve.

recoverMany Source #

Arguments

:: (Split plus err, Monad m) 
=> ResultT msg (Join plus err) m a

The try block

-> Handler plus ([msg] -> ResultT msg err m a) 
-> ResultT msg err m a 

Similarly to recover, but with more than one error type

See +> and eoh to build the Handler.

recoverManyWith Source #

Arguments

:: (HaveInstance c plus, Split plus err, Monad m) 
=> ResultT msg (Join plus err) m a

The try block

-> (forall e. c e => e -> [msg] -> ResultT msg err m a)

The typeclass-based error handler

-> ResultT msg err m a 

Similarly to recoverMany, but use the same error handler for every error types.

All the error types has to implement a given typeclass.

recoverManyDescriptive :: forall plus err msg m a. (HaveInstance DescriptiveError plus, Split plus err, Monad m) => ResultT msg (Join plus err) m a -> (forall e. DescriptiveError e => e -> [msg] -> ResultT msg err m a) -> ResultT msg err m a Source #

repeatUntil :: forall e err msg m a. Monad m => ResultT msg (e ': err) m () -> (e -> [msg] -> ResultT msg err m a) -> ResultT msg err m () Source #

Repeat a computation which may fail until it fails with a given error.

Typical use case is reading a file line by line, until reaching its end. If you want to carry some state, you can have a look at foldUntil.

repeatUntil' :: forall e err msg m. Monad m => ResultT msg (e ': err) m () -> ResultT msg err m () Source #

Same as repeatUntil, but without an error handler.

foldUntil Source #

Arguments

:: Monad m 
=> a

Initial state

-> (a -> ResultT msg (e ': err) m a) 
-> (a -> e -> [msg] -> ResultT msg err m a)

Error handler

-> ResultT msg err m a 

Similarly to repeatUntil, repeat a computation until a given error; in addition, carry an accumulator.

foldUntil' Source #

Arguments

:: Monad m 
=> a

Initial state

-> (a -> ResultT msg (e ': err) m a) 
-> ResultT msg err m a 

Same as foldUntil, but without the error handler part.

Leverage Existing Error Handling

eitherOr :: Monad m => Either e a -> a -> ResultT msg err m a Source #

exceptOr :: (Monad m, MonadError e m) => m a -> a -> ResultT msg err m a Source #

orAbort :: ('[e] :| err, Monad m) => Maybe a -> e -> ResultT msg err m a Source #

orAbortM :: ('[e] :| err, Monad m) => m (Maybe a) -> e -> ResultT msg err m a Source #

orElse :: Monad m => Maybe a -> a -> ResultT msg err m a Source #

orElseM :: Monad m => m (Maybe a) -> a -> ResultT msg err m a Source #

eitherAbort :: ('[e] :| err, Monad m) => Either e a -> ResultT msg err m a Source #

exceptAbort :: ('[e] :| err, MonadError e m) => m a -> ResultT msg err m a Source #

Set of Errors

data Handler set a Source #

type family set1 :| set2 :: Constraint where ... Source #

Equations

'[] :| set2 = () 
(e ': rst) :| set2 = (Contains set2 e, rst :| set2) 

(+>) :: (e -> a) -> Handler set a -> Handler (e ': set) a infixr 9 Source #

eoh :: Handler '[] a Source #

Stands for “end of handler”.

class HaveInstance c set where Source #

Minimal complete definition

generalize

Methods

generalize :: (forall e. c e => e -> a) -> Handler set a Source #

Instances

HaveInstance c ([] *) Source # 

Methods

generalize :: (forall e. c e => e -> a) -> Handler [*] a Source #

(HaveInstance c rst, c e) => HaveInstance c ((:) * e rst) Source # 

Methods

generalize :: (forall a. c a => a -> a) -> Handler ((* ': e) rst) a Source #

class DescriptiveError err where Source #

Minimal complete definition

describe

Methods

describe :: err -> String Source #