[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / docs / libraries / Exception.sgml
1 <sect> <idx/Exception/ 
2 <label id="sec:Exception">
3 <p>
4
5 The Exception library provides an interface for raising and catching
6 both built-in and user defined exceptions.
7
8 Exceptions are defined by the following (non-abstract) datatype:
9
10 <tscreen><verb>
11 data Exception
12   = IOException         IOError    -- IO exceptions (from 'fail')
13   | ArithException      ArithError -- Arithmetic exceptions
14   | ErrorCall           String     -- Calls to 'error'
15   | NoMethodError       String     -- A non-existent method was invoked
16   | PatternMatchFail    String     -- A pattern match failed
17   | NonExhaustiveGuards String     -- A guard match failed
18   | RecSelError         String     -- Selecting a non-existent field
19   | RecConError         String     -- Field missing in record construction
20   | RecUpdError         String     -- Record doesn't contain updated field
21   | AssertionFailed     String     -- Assertions
22   | DynException        Dynamic    -- Dynamic exceptions
23   | ExternalException   ExtError   -- External exceptions
24
25 instance Eq   Exception
26 instance Ord  Exception
27 instance Show Exception
28
29 data ArithError
30   = Overflow
31   | Underflow
32   | LossOfPrecision
33   | DivideByZero
34   | Denormal
35
36 instance Eq   ArithError
37 instance Ord  ArithError
38 instance Show ArithError
39
40 data ExtError
41   = StackOverflow
42   | HeapOverflow
43   | ThreadKilled
44
45 instance Eq   ExtError
46 instance Ord  ExtError
47 instance Show ExtError
48 </verb></tscreen>
49
50 An implementation should raise the appropriate exception when one of
51 the above conditions arises.  <em>Note: GHC currently doesn't generate
52 the arithmetic or the external exceptions.</em>
53
54 Exceptions may be thrown explicitly from anywhere:
55
56 <tscreen><verb>
57 throw :: Exception -> a
58 </verb></tscreen>
59
60 Exceptions may be caught and examined in the <tt/IO/ monad:
61
62 <tscreen><verb>
63 catch       :: IO a -> (Exception  -> IO a) -> IO a
64 catchIO     :: IO a -> (IOError    -> IO a) -> IO a
65 catchArith  :: IO a -> (ArithError -> IO a) -> IO a
66 catchError  :: IO a -> (String     -> IO a) -> IO a
67
68 getException   :: a -> IO (Maybe Exception)
69 getExceptionIO :: IO a -> IO (Either Exception a)
70 </verb></tscreen>
71
72 Each of the functions <tt/catchIO/, <tt/catchArith/, and
73 <tt/catchError/ only catch a specific type of exception.  All other
74 exceptions are effectively re-thrown.  An uncaught exception will
75 normally cause the program to terminate, with the offending exception
76 displayed.
77
78 Note that <tt/catchIO/ is identical to <tt/IO.catch/.  The
79 implementation of <tt/IO/ errors in GHC and Hugs uses exceptions for
80 speed.
81
82 Also, don't forget to <tt/import Prelude hidiing (catch)/ when using
83 this library, to avoid the name clash between <tt/Exception.catch/ and
84 <tt/IO.catch/.
85
86 The <tt/getException/ function is useful for evaluating a non-IO typed
87 value and testing for exceptions.  <tt/getException/ evaluates its
88 first argument (as if you'd applied <tt/seq/ to it), returning
89 <tt/Just &lt;exception&gt;/ if an exception was raised, or
90 <tt/Nothing/ otherwise.  Note that due to Haskell's unspecified
91 evaluation order, an expression may return one of several possible
92 exceptions: consider the expression <tt/error "urk" + 1 `div` 0/.  Does
93 <tt/getException/ return <tt/Just (ErrorCall "urk")/ or <tt/Just
94 (ArithError DivideByZero)/?  The answer is "either": getException
95 makes a non-deterministic choice about which exception to return.  If
96 you call it again, you might get a different exception back.  This is
97 ok, because <tt/getException/ is an IO computation.
98
99 <tt/getExceptionIO/ is the equivalent function for <tt/IO/ computations
100 --- it runs its first argument, and returns either the return value or
101 the exception if one was raised.  Passing a value of type <tt/IO a/ to
102 <tt/getException/ won't work, because the <tt/IO/ type is represented
103 by a function, and <tt/getException/ will only evaluate its argument
104 to head normal form, hence the <tt/IO/ computation won't be
105 performed.  Use <tt/getExceptionIO/ instead.
106
107 <sect1> <idx/Dynamic Exceptions/ 
108 <label id="sec:Dynamic-Exceptions">
109 <p>
110
111 Because the <tt/Exception/ datatype isn't extendible, we added an
112 interface for throwing and catching exceptions of type <tt/Dynamic/
113 (see Section <ref name="Dynamic" id="sec:Dynamic">), which allows
114 exception values of any type in the <tt/Typeable/ class to be thrown
115 and caught.
116
117 <tscreen><verb>
118 throwDyn :: Typeable exception => exception -> b
119 catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
120 </verb></tscreen>
121
122 The <tt/catchDyn/ function only catches exceptions of the required
123 type; all other exceptions are re-thrown as with <tt/catchIO/ and
124 friends above.
125