1 % -----------------------------------------------------------------------------
2 % $Id: Exception.lhs,v 1.2 1998/12/02 13:26:30 simonm Exp $
4 % (c) The GRAP/AQUA Project, Glasgow University, 1998
7 The External API for exceptions. The functions provided in this
8 module allow catching of exceptions in the IO monad.
13 Exception(..), -- instance Show
14 ArithError(..), -- instance Show
16 -- Throwing exceptions
18 throw, -- :: Exception -> a
20 -- Catching exceptions: The IO interface
22 catchException, -- :: IO a -> (Exception -> IO a) -> IO a
23 catch, -- :: IO a -> (IOError -> IO a) -> IO a
25 catchArith, -- :: IO a -> (ArithError -> IO a) -> IO a
26 catchError, -- :: IO a -> (String -> IO a) -> IO a
28 getException, -- :: a -> IO (Maybe Exception)
29 getExceptionIO, -- :: IO a -> IO (Either Exception a)
31 throwDyn, -- :: Typeable exception => exception -> b
32 catchDyn, -- :: Typeable exception =>
33 -- IO a -> (exception -> IO a) -> IO a
38 import PreludeBuiltin hiding (catch)
39 import Prelude hiding (catch)
41 import Prelude hiding (catch)
42 import PrelGHC (catch#)
43 import PrelException hiding (catch)
49 -----------------------------------------------------------------------------
50 Catch certain types of exception.
52 The following family of functions provide exception handling functions
53 for particular kinds of exceptions; all non-matching exceptions being
57 catchIO = Prelude.catch
59 catch = PreludeBuiltin.catchException
61 catch = PrelException.catchException
64 catchArith :: IO a -> (ArithError -> IO a) -> IO a
65 catchArith m k = catch m handler
66 where handler (ArithException err) = k err
67 handler other = throw other
69 catchError :: IO a -> (String -> IO a) -> IO a
70 catchError m k = catch m handler
71 where handler (ErrorCall err) = k err
72 handler other = throw other
75 -----------------------------------------------------------------------------
76 Dynamic exception types. Since one of the possible kinds of exception
77 is a dynamically typed value, we can effectively have polymorphic
80 throwDyn will raise any value as an exception, provided it is in the
81 Typeable class (see Dynamic.lhs).
83 catchDyn will catch any exception of a given type (determined by the
84 handler function). Any raised exceptions that don't match are
88 throwDyn :: Typeable exception => exception -> b
89 throwDyn exception = throw (DynException (toDyn exception))
91 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
92 catchDyn m k = catchException m handle
93 where handle ex = case ex of
95 case fromDynamic dyn of
96 Just exception -> k exception
101 -----------------------------------------------------------------------------
102 Some Useful Functions
106 getException :: a -> IO (Maybe Exception)
107 getException a = primCatch' (case primForce a of { () -> return Nothing}) (\e -> return (Just e))
109 getException :: a -> IO (Maybe Exception)
110 getException a = catch# (a `seq` return Nothing) (\e -> return (Just e))
113 getExceptionIO :: IO a -> IO (Either Exception a)
114 getExceptionIO m = catchException (m >>= \ r -> return (Right r))
115 (\ e -> return (Left e))