Skip to content

Commit 273530a

Browse files
committed
Add laws for MonadError
1 parent 5ae7255 commit 273530a

File tree

1 file changed

+31
-22
lines changed

1 file changed

+31
-22
lines changed

Control/Monad/Error/Class.hs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Maintainer : libraries@haskell.org
1616
Stability : experimental
1717
Portability : non-portable (multi-parameter type classes)
1818
19-
[Computation type:] Computations which may fail or throw exceptions.
19+
[Computation type:] Computations which may throw exceptions.
2020
2121
[Binding strategy:] Failure records information about the cause\/location
2222
of the failure. Failure values bypass the bound function,
@@ -72,30 +72,39 @@ import Control.Monad.Instances ()
7272
import Data.Monoid
7373
import Prelude (Either(..), Maybe(..), either, (.), IO)
7474

75-
{- |
76-
The strategy of combining computations that can throw exceptions
77-
by bypassing bound functions
78-
from the point an exception is thrown to the point that it is handled.
79-
80-
Is parameterized over the type of error information and
81-
the monad type constructor.
82-
It is common to use @'Either' String@ as the monad type constructor
83-
for an error monad in which error descriptions take the form of strings.
84-
In that case and many other common cases the resulting monad is already defined
85-
as an instance of the 'MonadError' class.
86-
You can also define your own error type and\/or use a monad type constructor
87-
other than @'Either' 'String'@ or @'Either' 'IOError'@.
88-
In these cases you will have to explicitly define instances of the 'MonadError'
89-
class.
90-
(If you are using the deprecated "Control.Monad.Error" or
91-
"Control.Monad.Trans.Error", you may also have to define an 'Error' instance.)
92-
-}
75+
-- | Monads with a notion of exceptions which can be thrown and caught.
76+
--
77+
-- === Laws
78+
--
79+
-- 'catchError' and 'throwError' form a monad, with @('>>=')@
80+
-- interpreted as 'catchError' and 'pure' as 'throwError'.
81+
--
82+
-- @
83+
-- 'catchError' ('throwError' e) h = h e
84+
-- 'catchError' m 'throwError' = m
85+
-- 'catchError' ('catchError' m k) h = 'catchError' m (\\e -> 'catchError' (k e) h)
86+
-- @
87+
--
88+
-- 'pure' and 'throwError' are left zeros for 'catchError' and @('>>=')@
89+
-- respectively.
90+
--
91+
-- @
92+
-- 'catchError' ('pure' a) h = 'pure' a
93+
-- 'throwError' e '>>=' k = 'throwError' e
94+
-- @
95+
--
96+
-- 'catchError' commutes with 'fmap' (it is a natual transformation).
97+
--
98+
-- @
99+
-- 'fmap' f ('catchError' u h) = 'catchError' ('fmap' f u) ('fmap' f '.' h)
100+
-- @
101+
--
102+
-- The last two laws are guaranteed by parametricity.
93103
class (Monad m) => MonadError e m | m -> e where
94-
-- | Is used within a monadic computation to begin exception processing.
104+
-- | Throw an exception.
95105
throwError :: e -> m a
96106

97-
{- |
98-
A handler function to handle previous errors and return to normal execution.
107+
{- | Handle an exception and return to normal execution.
99108
A common idiom is:
100109
101110
> do { action1; action2; action3 } `catchError` handler

0 commit comments

Comments
 (0)