@@ -1,33 +1,33 @@
1−-- | Support for checked exceptions.
1+-- | Support for handling errors of a particular type, i.e. checked exceptions.
3−-- /Note:/ the 'Error' effect provided by this module is a suitable replacement
3+-- /Note:/ the 'Error' effect is a suitable replacement for the
4−-- for the "Control.Monad.Trans.Except" monad transformer found in the
4+-- 'Control.Monad.Trans.Except.ExceptT' monad transformer from the
5-- @transformers@ library. It is __not__ a general mechanism for handling
5-- @transformers@ library. It is __not__ a general mechanism for handling
6−-- exceptions, that's what functions from the "Control.Monad.Catch" module are
6+-- exceptions, that's what functions from the @exceptions@ library are for (see
7−-- for.
7+-- "Control.Monad.Catch" for more information).
9−-- For example, if you want to catch an unchecked exception like
9+-- In particular, exceptions of type @e@ are distinct from errors of type @e@
10−-- 'Control.Exception.ErrorCall' you could use 'Control.Monad.Catch.catch':
10+-- and will __not__ be caught by functions from this module:
12-- >>> import qualified Control.Monad.Catch as E
12-- >>> import qualified Control.Monad.Catch as E
13-- >>> let boom = error "BOOM!"
13-- >>> let boom = error "BOOM!"
14−-- >>> runEff $ boom `E.catch` \(_::ErrorCall) -> pure "caught an error"
17−-- In particular, unchecked exceptions of type @e@ are distinct from errors of
18−-- type @e@ and will __not__ be caught by functions from this module:
20−-- >>> runEff . runError @ErrorCall $ boom `catchError` \_ (_::ErrorCall) -> pure "caught an error"
14+-- >>> runEff . runError @ErrorCall $ boom `catchError` \_ (_::ErrorCall) -> pure "caught"
21-- *** Exception: BOOM!
15-- *** Exception: BOOM!
18+-- If you want to catch regular exceptions, you should use
19+-- 'Control.Monad.Catch.catch' (or a similar function):
21+-- >>> runEff $ boom `E.catch` \(_::ErrorCall) -> pure "caught"
24-- On the other hand, functions for safe finalization and management of
24-- On the other hand, functions for safe finalization and management of
25-- resources such as 'Control.Monad.Catch.finally' and
25-- resources such as 'Control.Monad.Catch.finally' and
26-- 'Control.Monad.Catch.bracket' work as expected:
26-- 'Control.Monad.Catch.bracket' work as expected:
28-- >>> let display = liftIO . putStrLn
28-- >>> let display = liftIO . putStrLn
30−-- runEff . fmap (first snd) . runError @String $ do
30+-- runEff . fmap (either (Left . snd) Right) . runError @String $ do
31-- E.bracket_ (display "Beginning.")
31-- E.bracket_ (display "Beginning.")
32-- (display "Cleaning up.")
32-- (display "Cleaning up.")
33-- (display "Computing." >> throwError "oops" >> display "More.")
33-- (display "Computing." >> throwError "oops" >> display "More.")
@@ -61,7 +61,7 @@ import GHC.Stack
61import Effectful.Dispatch.Static
61import Effectful.Dispatch.Static
62import Effectful.Monad
62import Effectful.Monad
64−-- | Provide the capability of handling errors of type @e@.
64+-- | Provide the ability to handle errors of type @e@.
65newtype Error e :: Effect where
65newtype Error e :: Effect where
66 Error :: ErrorId -> Error e m r
66 Error :: ErrorId -> Error e m r
@@ -167,6 +167,3 @@ catchErrorIO eid m handler = do
167 if eid == etag
167 if eid == etag
168 then handler e cs
168 then handler e cs
169 else throwIO err
169 else throwIO err
172−-- >>> import Data.Bifunctor