1 % -----------------------------------------------------------------------------
2 % $Id: Exception.lhs,v 1.4 1999/01/14 18:15:29 sof 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 ArithException(..), -- instance Show
15 AsyncException(..), -- instance Show
17 tryAll, -- :: a -> IO (Either Exception a)
18 tryAllIO, -- :: IO a -> IO (Either Exception a)
19 try, -- :: (Exception -> Maybe b) -> a -> IO (Either b a)
20 tryIO, -- :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
22 catchAll, -- :: a -> (Exception -> IO a) -> IO a
23 catchAllIO,-- :: IO a -> (Exception -> IO a) -> IO a
24 catch, -- :: (Exception -> Maybe b) -> a -> (b -> IO a) -> IO a
25 catchIO, -- :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
27 -- Exception predicates
29 justIoErrors, -- :: Exception -> Maybe IOError
30 justArithExceptions, -- :: Exception -> Maybe ArithException
31 justErrors, -- :: Exception -> Maybe String
32 justDynExceptions, -- :: Exception -> Maybe Dynamic
33 justAssertions, -- :: Exception -> Maybe String
34 justAsyncExceptions, -- :: Exception -> Maybe AsyncException
36 -- Throwing exceptions
38 throw, -- :: Exception -> a
42 throwDyn, -- :: Typeable ex => ex -> b
43 catchDyn, -- :: Typeable ex => IO a -> (ex -> IO a) -> IO a
47 finally, -- :: IO a -> IO b -> IO b
49 bracket, -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
50 bracket_, -- :: IO a -> IO b -> IO c -> IO ()
55 import PreludeBuiltin hiding (catch)
56 import Prelude hiding (catch)
58 import Prelude hiding (catch)
59 import PrelGHC (catch#)
60 import PrelException hiding (catch)
66 -----------------------------------------------------------------------------
69 PrelException defines 'catchException' for us.
72 catchAll :: a -> (Exception -> IO a) -> IO a
74 catchAll a handler = primCatch' (case primForce a of () -> return a) handler
76 catchAll a handler = catch# (a `seq` return a) handler
79 catchAllIO :: IO a -> (Exception -> IO a) -> IO a
80 catchAllIO = catchException
82 catch :: (Exception -> Maybe b) -> a -> (b -> IO a) -> IO a
83 catch p a handler = catchAll a handler'
84 where handler' e = case p e of
88 catchIO :: (Exception -> Maybe b) -> IO a -> (b -> IO a) -> IO a
89 catchIO p a handler = catchAllIO a handler'
90 where handler' e = case p e of
95 -----------------------------------------------------------------------------
99 tryAll :: a -> IO (Either Exception a)
101 tryAll a = primCatch' (case primForce a of { () -> return Nothing})
102 (\e -> return (Just e))
104 tryAll a = catch# (a `seq` return (Right a)) (\e -> return (Left e))
107 tryAllIO :: IO a -> IO (Either Exception a)
108 tryAllIO a = catchAllIO (a >>= \ v -> return (Right v))
109 (\e -> return (Left e))
111 try :: (Exception -> Maybe b) -> a -> IO (Either b a)
115 Right v -> return (Right v)
116 Left e -> case p e of
118 Just b -> return (Left b)
120 tryIO :: (Exception -> Maybe b) -> IO a -> IO (Either b a)
124 Right v -> return (Right v)
125 Left e -> case p e of
127 Just b -> return (Left b)
130 -----------------------------------------------------------------------------
131 Dynamic exception types. Since one of the possible kinds of exception
132 is a dynamically typed value, we can effectively have polymorphic
135 throwDyn will raise any value as an exception, provided it is in the
136 Typeable class (see Dynamic.lhs).
138 catchDyn will catch any exception of a given type (determined by the
139 handler function). Any raised exceptions that don't match are
143 throwDyn :: Typeable exception => exception -> b
144 throwDyn exception = throw (DynException (toDyn exception))
146 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
147 catchDyn m k = catchException m handle
148 where handle ex = case ex of
149 (DynException dyn) ->
150 case fromDynamic dyn of
151 Just exception -> k exception
156 -----------------------------------------------------------------------------
160 justIoErrors :: Exception -> Maybe IOError
161 justArithExceptions :: Exception -> Maybe ArithException
162 justErrors :: Exception -> Maybe String
163 justDynExceptions :: Exception -> Maybe Dynamic
164 justAssertions :: Exception -> Maybe String
165 justAsyncExceptions :: Exception -> Maybe AsyncException
167 justIoErrors (IOException e) = Just e
168 justIoErrors _ = Nothing
170 justArithExceptions (ArithException e) = Just e
171 justArithExceptions _ = Nothing
173 justErrors (ErrorCall e) = Just e
174 justErrors _ = Nothing
176 justAssertions (AssertionFailed e) = Just e
177 justAssertions _ = Nothing
179 justDynExceptions (DynException e) = Just e
180 justDynExceptions _ = Nothing
182 justAsyncExceptions (AsyncException e) = Just e
183 justAsyncExceptions _ = Nothing
186 -----------------------------------------------------------------------------
187 Some Useful Functions
190 finally :: IO a -> IO b -> IO b
191 a `finally` sequel = do
195 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO ()
196 bracket before after thing = do
198 c <- tryAllIO (thing a)
202 bracket_ :: IO a -> IO b -> IO c -> IO ()
203 bracket_ before after thing = do