Have validate take into account stat test failures too.
[ghc.git] / libraries / base / GHC / Exception.lhs
1 \begin{code}
2 {-# LANGUAGE Trustworthy #-}
3 {-# LANGUAGE NoImplicitPrelude
4            , ExistentialQuantification
5            , MagicHash
6            , DeriveDataTypeable
7   #-}
8 {-# OPTIONS_HADDOCK hide #-}
9
10 -----------------------------------------------------------------------------
11 -- |
12 -- Module      :  GHC.Exception
13 -- Copyright   :  (c) The University of Glasgow, 1998-2002
14 -- License     :  see libraries/base/LICENSE
15 --
16 -- Maintainer  :  cvs-ghc@haskell.org
17 -- Stability   :  internal
18 -- Portability :  non-portable (GHC extensions)
19 --
20 -- Exceptions and exception-handling functions.
21 --
22 -----------------------------------------------------------------------------
23
24 module GHC.Exception
25        ( Exception(..)    -- Class
26        , throw
27        , SomeException(..), ErrorCall(..), ArithException(..)
28        , divZeroException, overflowException, ratioZeroDenomException
29        , errorCallException
30        ) where
31
32 import Data.Maybe
33 import Data.Typeable (Typeable, cast)
34    -- loop: Data.Typeable -> GHC.Err -> GHC.Exception
35 import GHC.Base
36 import GHC.Show
37 \end{code}
38
39 %*********************************************************
40 %*                                                      *
41 \subsection{Exceptions}
42 %*                                                      *
43 %*********************************************************
44
45 \begin{code}
46 {- |
47 The @SomeException@ type is the root of the exception type hierarchy.
48 When an exception of type @e@ is thrown, behind the scenes it is
49 encapsulated in a @SomeException@.
50 -}
51 data SomeException = forall e . Exception e => SomeException e
52     deriving Typeable
53
54 instance Show SomeException where
55     showsPrec p (SomeException e) = showsPrec p e
56
57 {- |
58 Any type that you wish to throw or catch as an exception must be an
59 instance of the @Exception@ class. The simplest case is a new exception
60 type directly below the root:
61
62 > data MyException = ThisException | ThatException
63 >     deriving (Show, Typeable)
64 >
65 > instance Exception MyException
66
67 The default method definitions in the @Exception@ class do what we need
68 in this case. You can now throw and catch @ThisException@ and
69 @ThatException@ as exceptions:
70
71 @
72 *Main> throw ThisException \`catch\` \\e -> putStrLn (\"Caught \" ++ show (e :: MyException))
73 Caught ThisException
74 @
75
76 In more complicated examples, you may wish to define a whole hierarchy
77 of exceptions:
78
79 > ---------------------------------------------------------------------
80 > -- Make the root exception type for all the exceptions in a compiler
81 >
82 > data SomeCompilerException = forall e . Exception e => SomeCompilerException e
83 >     deriving Typeable
84 >
85 > instance Show SomeCompilerException where
86 >     show (SomeCompilerException e) = show e
87 >
88 > instance Exception SomeCompilerException
89 >
90 > compilerExceptionToException :: Exception e => e -> SomeException
91 > compilerExceptionToException = toException . SomeCompilerException
92 >
93 > compilerExceptionFromException :: Exception e => SomeException -> Maybe e
94 > compilerExceptionFromException x = do
95 >     SomeCompilerException a <- fromException x
96 >     cast a
97 >
98 > ---------------------------------------------------------------------
99 > -- Make a subhierarchy for exceptions in the frontend of the compiler
100 >
101 > data SomeFrontendException = forall e . Exception e => SomeFrontendException e
102 >     deriving Typeable
103 >
104 > instance Show SomeFrontendException where
105 >     show (SomeFrontendException e) = show e
106 >
107 > instance Exception SomeFrontendException where
108 >     toException = compilerExceptionToException
109 >     fromException = compilerExceptionFromException
110 >
111 > frontendExceptionToException :: Exception e => e -> SomeException
112 > frontendExceptionToException = toException . SomeFrontendException
113 >
114 > frontendExceptionFromException :: Exception e => SomeException -> Maybe e
115 > frontendExceptionFromException x = do
116 >     SomeFrontendException a <- fromException x
117 >     cast a
118 >
119 > ---------------------------------------------------------------------
120 > -- Make an exception type for a particular frontend compiler exception
121 >
122 > data MismatchedParentheses = MismatchedParentheses
123 >     deriving (Typeable, Show)
124 >
125 > instance Exception MismatchedParentheses where
126 >     toException   = frontendExceptionToException
127 >     fromException = frontendExceptionFromException
128
129 We can now catch a @MismatchedParentheses@ exception as
130 @MismatchedParentheses@, @SomeFrontendException@ or
131 @SomeCompilerException@, but not other types, e.g. @IOException@:
132
133 @
134 *Main> throw MismatchedParentheses `catch` \e -> putStrLn (\"Caught \" ++ show (e :: MismatchedParentheses))
135 Caught MismatchedParentheses
136 *Main> throw MismatchedParentheses `catch` \e -> putStrLn (\"Caught \" ++ show (e :: SomeFrontendException))
137 Caught MismatchedParentheses
138 *Main> throw MismatchedParentheses `catch` \e -> putStrLn (\"Caught \" ++ show (e :: SomeCompilerException))
139 Caught MismatchedParentheses
140 *Main> throw MismatchedParentheses `catch` \e -> putStrLn (\"Caught \" ++ show (e :: IOException))
141 *** Exception: MismatchedParentheses
142 @
143
144 -}
145 class (Typeable e, Show e) => Exception e where
146     toException   :: e -> SomeException
147     fromException :: SomeException -> Maybe e
148
149     toException = SomeException
150     fromException (SomeException e) = cast e
151
152 instance Exception SomeException where
153     toException se = se
154     fromException = Just
155 \end{code}
156
157 %*********************************************************
158 %*                                                      *
159 \subsection{Primitive throw}
160 %*                                                      *
161 %*********************************************************
162
163 \begin{code}
164 -- | Throw an exception.  Exceptions may be thrown from purely
165 -- functional code, but may only be caught within the 'IO' monad.
166 throw :: Exception e => e -> a
167 throw e = raise# (toException e)
168 \end{code}
169
170 \begin{code}
171 -- |This is thrown when the user calls 'error'. The @String@ is the
172 -- argument given to 'error'.
173 newtype ErrorCall = ErrorCall String
174     deriving (Eq, Ord, Typeable)
175
176 instance Exception ErrorCall
177
178 instance Show ErrorCall where
179     showsPrec _ (ErrorCall err) = showString err
180
181 errorCallException :: String -> SomeException
182 errorCallException s = toException (ErrorCall s)
183
184 -----
185
186 -- |Arithmetic exceptions.
187 data ArithException
188   = Overflow
189   | Underflow
190   | LossOfPrecision
191   | DivideByZero
192   | Denormal
193   | RatioZeroDenominator -- ^ /Since: 4.6.0.0/
194   deriving (Eq, Ord, Typeable)
195
196 divZeroException, overflowException, ratioZeroDenomException  :: SomeException
197 divZeroException        = toException DivideByZero
198 overflowException       = toException Overflow
199 ratioZeroDenomException = toException RatioZeroDenominator
200
201 instance Exception ArithException
202
203 instance Show ArithException where
204   showsPrec _ Overflow        = showString "arithmetic overflow"
205   showsPrec _ Underflow       = showString "arithmetic underflow"
206   showsPrec _ LossOfPrecision = showString "loss of precision"
207   showsPrec _ DivideByZero    = showString "divide by zero"
208   showsPrec _ Denormal        = showString "denormal"
209   showsPrec _ RatioZeroDenominator = showString "Ratio has zero denominator"
210 \end{code}