on test-disable-tup-instances help sign in
127 lines 3.4 kB history raw
1module Ether.Except
2 (
3 -- * MonadExcept class
4 MonadExcept
5 , throw
6 , catch
7 -- * The Except monad
8 , Except
9 , runExcept
10 -- * The ExceptT monad transformer
11 , ExceptT
12 , exceptT
13 , runExceptT
14 -- * MonadExcept class (implicit)
15 , MonadExcept'
16 , throw'
17 , catch'
18 -- * The Except monad (implicit)
19 , Except'
20 , runExcept'
21 -- * The ExceptT monad transformer (implicit)
22 , ExceptT'
23 , exceptT'
24 , runExceptT'
25 -- * Internal labels
26 , TAGGED
27 , EXCEPT
28 ) where
30import qualified Control.Monad.Except as T
31import Control.Monad.Signatures (Catch)
32import qualified Control.Monad.Trans.Lift.Catch as Lift
33import Data.Coerce
34import Data.Functor.Identity
36import Ether.TaggedTrans
37import Ether.Internal
39class Monad m => MonadExcept tag e m | m tag -> e where
41 -- | Is used within a monadic computation to begin exception processing.
42 throw :: e -> m a
44 -- | A TaggedTrans function to handle previous exceptions and return to
45 -- normal execution.
46 catch :: m a -> (e -> m a) -> m a
48instance {-# OVERLAPPABLE #-}
49 ( Lift.LiftCatch t
50 , Monad (t m)
51 , MonadExcept tag e m
52 ) => MonadExcept tag e (t m) where
53 throw = Lift.lift . throw @tag
54 catch = Lift.liftCatch (catch @tag)
56-- | Encode type-level information for 'ExceptT'.
57data EXCEPT
59-- | The parameterizable exception monad.
60--
61-- Computations are either exceptions or normal values.
62--
63-- The 'return' function returns a normal value, while '>>=' exits on
64-- the first exception.
65type Except tag e = ExceptT tag e Identity
67-- | The exception monad transformer.
68--
69-- The 'return' function returns a normal value, while '>>=' exits on
70-- the first exception.
71type ExceptT tag e = TaggedTrans (TAGGED EXCEPT tag) (T.ExceptT e)
73-- | Runs an 'Except' and returns either an exception or a normal value.
74runExcept :: forall tag e a . Except tag e a -> Either e a
75runExcept = coerce (T.runExcept @e @a)
77-- | Runs an 'ExceptT' and returns either an exception or a normal value.
78runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
79runExceptT = coerce (T.runExceptT @e @m @a)
81-- | Constructor for computations in the exception monad transformer.
82exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
83exceptT = coerce (T.ExceptT @e @m @a)
85type instance HandleSuper EXCEPT e trans = ()
86type instance HandleConstraint EXCEPT e trans m =
87 T.MonadError e (trans m)
89instance Handle EXCEPT e (T.ExceptT e) where
90 handling r = r
92instance
93 ( Handle EXCEPT e trans
94 , Monad m, Monad (trans m)
95 ) => MonadExcept tag e (TaggedTrans (TAGGED EXCEPT tag) trans m)
96 where
98 throw =
99 handling @EXCEPT @e @trans @m $
100 coerce (T.throwError @e @(trans m) @a) ::
101 forall eff a . e -> TaggedTrans eff trans m a
103 catch =
104 handling @EXCEPT @e @trans @m $
105 coerce (T.catchError @e @(trans m) @a) ::
106 forall eff a . Catch e (TaggedTrans eff trans m) a
108type MonadExcept' e = MonadExcept e e
110throw' :: forall e m a . MonadExcept' e m => e -> m a
111throw' = throw @e
113catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
114catch' = catch @e
116type Except' e = Except e e
118runExcept' :: Except' e a -> Either e a
119runExcept' = runExcept
121type ExceptT' e = ExceptT e e
123exceptT' :: m (Either e a) -> ExceptT' e m a
124exceptT' = exceptT
126runExceptT' :: ExceptT' e m a -> m (Either e a)
127runExceptT' = runExceptT