checked-exceptions-0.1.0.0: lib/Control/Monad/CheckedExcept/QualifiedDo.hs
{-# LANGUAGE
TypeApplications
, ScopedTypeVariables
, LambdaCase
#-}
module Control.Monad.CheckedExcept.QualifiedDo
( (>>=)
, (>>)
, pure
, return
, fail
) where
import Control.Monad.CheckedExcept
import Prelude hiding (Monad(..), Applicative(..), MonadFail(..))
import qualified Prelude
-- | Bind operator for 'CheckedExceptT' that allows chaining computations
-- that may expand the exception set.
(>>=) :: forall exceptions1 exceptions2 exceptions3 m a.
( Contains exceptions1 exceptions3
, Contains exceptions2 exceptions3
, Prelude.Monad m
)
=> CheckedExceptT exceptions1 m a
-> (a -> CheckedExceptT exceptions2 m a)
-> CheckedExceptT exceptions3 m a
m >>= f = do
CheckedExceptT $ do
runCheckedExceptT m Prelude.>>= \case
Left e -> Prelude.pure $ Left (weakenOneOf @exceptions1 @exceptions3 e)
Right a -> runCheckedExceptT (weakenExceptions (f a))
-- | 'pure' function for 'CheckedExceptT'.
pure :: Prelude.Monad m => a -> CheckedExceptT es m a
pure = Prelude.pure
-- | 'return' function for 'CheckedExceptT'.
return :: Prelude.Monad m => a -> CheckedExceptT es m a
return = Prelude.return
-- | Sequentially compose two actions, discarding any value produced by the first.
(>>) :: forall exceptions1 exceptions2 exceptions3 m a x.
( Contains exceptions1 exceptions3
, Contains exceptions2 exceptions3
, Prelude.Monad m
)
=> CheckedExceptT exceptions1 m x
-> CheckedExceptT exceptions2 m a
-> CheckedExceptT exceptions3 m a
a >> b = weakenExceptions a Prelude.>> weakenExceptions b
-- | 'fail' function for 'CheckedExceptT'.
fail :: Prelude.MonadFail m => String -> CheckedExceptT es m a
fail = Prelude.fail
{-
Example usage:
module CompTest where
import Control.Monad.CheckedExcept
import Control.Monad.Trans.Class (lift)
import qualified Control.Monad.CheckedExcept.QualifiedDo as CheckedExcept
testCE1 :: CheckedExceptT '[()] IO ()
testCE1 = CheckedExcept.do
lift $ putStrLn "1"
lift $ pure ()
pure ()
testCE2 :: CheckedExceptT '[Int] IO ()
testCE2 = CheckedExcept.do
lift $ putStrLn "2"
throwCheckedException (1 :: Int)
pure ()
testCE3 :: CheckedExceptT '[Bool] IO ()
testCE3 = CheckedExcept.do
lift $ putStrLn "3"
throwCheckedException False
pure ()
testCE4 :: CheckedExceptT '[String] IO ()
testCE4 = CheckedExcept.do
lift $ putStrLn "4"
throwCheckedException "err"
pure ()
testCE5 :: CheckedExceptT '[Char] IO ()
testCE5 = CheckedExcept.do
lift $ putStrLn "5"
throwCheckedException 'c'
pure ()
testCE :: CheckedExceptT '[(), Int, Bool, String] IO ()
testCE = CheckedExcept.do
() <- testCE1
() <- testCE2
() <- testCE3
() <- testCE4
-- () <- testCE5 -- doesn't compile
pure ()
test :: CheckedExcept TestExceptions () -> IO ()
test ce = case runCheckedExcept ce of
Left e -> do
applyAll (putStrLn . encodeException) e
-- or
withOneOf @() e $ \() -> putStrLn "()"
withOneOf @Int e $ \n -> print $ n + 1
withOneOf @Bool e $ \_ -> pure ()
-- or
caseException e
( (\() -> putStrLn "()")
<: (\n -> print $ n + 1)
<: CaseAny (\x -> putStrLn $ encodeException x)
-- <: (\b -> putStrLn "bool")
-- <: (\s -> putStrLn "string")
-- <: CaseEnd
)
Right () -> putStrLn "Right"
type TestExceptions = '[(), Int, Bool, String]
deriving via (ShowException ()) instance CheckedException ()
deriving via (ShowException Int) instance CheckedException Int
deriving via (ShowException Bool) instance CheckedException Bool
deriving via (ShowException String) instance CheckedException [Char]
deriving via (ShowException Char) instance CheckedException Char
-}