Copyright | (c) Jamaal Malek <mjm540@york.ac.uk> 2014 |
---|---|
License | BSD3 |
Maintainer | mjm540@york.ac.uk |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
Control.Monad.Except.Backtracking
Description
- data BExceptT e m a
- bExceptT :: Monad m => m (Either e a) -> BExceptT e m a
- runBExceptT :: Monad m => BExceptT e m a -> m (Either e a)
- hoistEither :: Monad m => Either e a -> BExceptT e m a
- module Control.Monad.Error.Class
The BExceptT monad transformer
BExceptT
is a monad transformer that adds backtracking exception handling to its base monad.
Instances
(Functor m, MonadRWS r w s m) => MonadRWS r w s (BExceptT e m) | |
MonadState s m => MonadState s (BExceptT e m) | |
MonadReader r m => MonadReader r (BExceptT e m) | |
(Functor f, MonadFree f m) => MonadFree f (BExceptT e m) | |
Monad m => MonadError e (BExceptT e m) | |
(Functor m, MonadWriter w m) => MonadWriter w (BExceptT e m) | |
MonadTrans (BExceptT e) | |
(Monad m, Semigroup e, Monoid e) => Alternative (BExceptT e m) | |
Monad (BExceptT e m) | |
Functor (BExceptT e m) | |
(Monad m, Semigroup e, Monoid e) => MonadPlus (BExceptT e m) | |
Applicative (BExceptT e m) | |
MonadIO m => MonadIO (BExceptT e m) | |
(Monad m, Semigroup e, Monoid e) => Plus (BExceptT e m) | |
(Monad m, Semigroup e) => Alt (BExceptT e m) | |
Apply (BExceptT e m) |
runBExceptT :: Monad m => BExceptT e m a -> m (Either e a) Source
runBExceptT
does the opposite of bExceptT
hoistEither :: Monad m => Either e a -> BExceptT e m a Source
hoistEither
constructs a BExceptT
from an Either
value.
module Control.Monad.Error.Class
Usage example and explanation
The following example shows the basic operation of the BExceptT
monad.
example1 :: StateT Int (BExceptT String IO) () example1 = do put 1 catchError (put 2) $ \e -> do i <- get liftIO $ do putStrLn $ "caught an error: '" <|> e <|> "'" putStrLn $ "setting i to 4, current value is " <|> show i put 4 i <- get when (i /= 4) $ put 3 liftIO $ putStrLn "reading i" i <- get when (i /= 4) $ throwError "i isnt 4" runexample1 :: IO (Either String ((), Int)) runexample1 = runBExceptT $ flip runStateT 0 example1
The output produced is:
reading i caught an error: 'i isnt 4' setting i to 4, current value is 1 reading i Right ((),4)
At first, the execution proceeds normally, setting the state to 1, then 2, then 3. The final line throws an exception because the state is 3, not 4. The execution then backtracks to before put 2
was executed. The state has been restored to 1 at this stage. The exception handler applied to put 2
is executed, and execution continues from the line below.
Replacing when (i /= 4) $ put 3
with put 3
will not create an infinite loop, after the failure of each exception handler (in this case there is only one) execution will stop and return an error.
Using
instead of BExceptT
String
(StateT
Int
IO
) ()
means that the state will not be restored after an error.StateT
Int
(BExceptT
String
IO
) ()
The Alternative
and MonadPlus
instances of BExceptT
can be used like the instances in a nondeterminism monad, such as the list monad, except only one successful result at most will be returned.