import System.IO.Unsafe (unsafePerformIO)
import Data.Dynamic
+#ifdef __NHC__
+import System.IO.Error (catch, ioError)
+import IO (bracket)
+import DIOError -- defn of IOError type
+
+-- minimum needed for nhc98 to pretend it has Exceptions
+type Exception = IOError
+type IOException = IOError
+data ArithException
+data ArrayException
+data AsyncException
+
+throwIO :: Exception -> IO a
+throwIO = ioError
+throw :: Exception -> a
+throw = unsafePerformIO . throwIO
+
+evaluate :: a -> IO a
+evaluate x = x `seq` return x
+
+ioErrors :: Exception -> Maybe IOError
+ioErrors e = Just e
+arithExceptions :: Exception -> Maybe ArithException
+arithExceptions = const Nothing
+errorCalls :: Exception -> Maybe String
+errorCalls = const Nothing
+dynExceptions :: Exception -> Maybe Dynamic
+dynExceptions = const Nothing
+assertions :: Exception -> Maybe String
+assertions = const Nothing
+asyncExceptions :: Exception -> Maybe AsyncException
+asyncExceptions = const Nothing
+userErrors :: Exception -> Maybe String
+userErrors (UserError _ s) = Just s
+userErrors _ = Nothing
+
+block :: IO a -> IO a
+block = id
+unblock :: IO a -> IO a
+unblock = id
+
+assert :: Bool -> a -> a
+assert True x = x
+assert False _ = throw (UserError "" "Assertion failed")
+#endif
+
-----------------------------------------------------------------------------
-- Catching exceptions
-- argument. Otherwise, the result is returned as normal. For example:
--
-- > catch (openFile f ReadMode)
--- > (\e -> hPutStr stderr (\"Couldn\'t open \"++f++\": \" ++ show e))
+-- > (\e -> hPutStr stderr ("Couldn't open "++f++": " ++ show e))
--
-- For catching exceptions in pure (non-'IO') expressions, see the
-- function 'evaluate'.
-- Also note that the "Prelude" also exports a function called
-- 'Prelude.catch' with a similar type to 'Control.Exception.catch',
-- except that the "Prelude" version only catches the IO and user
--- families of exceptions (as required by Haskell 98). We recommend
--- either hiding the "Prelude" version of
--- 'Prelude.catch' when importing
--- "Control.Exception", or importing
--- "Control.Exception" qualified, to avoid name-clashes.
-
+-- families of exceptions (as required by Haskell 98).
+--
+-- We recommend either hiding the "Prelude" version of 'Prelude.catch'
+-- when importing "Control.Exception":
+--
+-- > import Prelude hiding (catch)
+--
+-- or importing "Control.Exception" qualified, to avoid name-clashes:
+--
+-- > import qualified Control.Exception as C
+--
+-- and then using @C.catch@
+--
+#ifndef __NHC__
catch :: IO a -- ^ The computation to run
-> (Exception -> IO a) -- ^ Handler to invoke if an exception is raised
-> IO a
catch = ExceptionBase.catchException
-
+#endif
-- | The function 'catchJust' is like 'catch', but it takes an extra
-- argument which is an /exception predicate/, a function which
-- selects which type of exceptions we\'re interested in. There are
-- @('Right' a)@ if no exception was raised, or @('Left' e)@ if an
-- exception was raised and its value is @e@.
--
--- > try a = catch (Right \`liftM\` a) (return . Left)
+-- > try a = catch (Right `liftM` a) (return . Left)
--
-- Note: as with 'catch', it is only polite to use this variant if you intend
-- to re-throw the exception after performing whatever cleanup is needed.
-- | Raise any value as an exception, provided it is in the
-- 'Typeable' class.
throwDyn :: Typeable exception => exception -> b
+#ifdef __NHC__
+throwDyn exception = throw (UserError "" "dynamic exception")
+#else
throwDyn exception = throw (DynException (toDyn exception))
+#endif
#ifdef __GLASGOW_HASKELL__
-- | A variant of 'throwDyn' that throws the dynamic exception to an
-- with dynamic exceptions used in other libraries.
--
catchDyn :: Typeable exception => IO a -> (exception -> IO a) -> IO a
+#ifdef __NHC__
+catchDyn m k = m -- can't catch dyn exceptions in nhc98
+#else
catchDyn m k = catchException m handle
where handle ex = case ex of
(DynException dyn) ->
Just exception -> k exception
Nothing -> throw ex
_ -> throw ex
+#endif
-----------------------------------------------------------------------------
-- Exception Predicates
-- These pre-defined predicates may be used as the first argument to
-- 'catchJust', 'tryJust', or 'handleJust' to select certain common
-- classes of exceptions.
-
+#ifndef __NHC__
ioErrors :: Exception -> Maybe IOError
arithExceptions :: Exception -> Maybe ArithException
errorCalls :: Exception -> Maybe String
userErrors (IOException e) | isUserError e = Just (ioeGetErrorString e)
userErrors _ = Nothing
-
+#endif
-----------------------------------------------------------------------------
-- Some Useful Functions
-- The arguments to 'bracket' are in this order so that we can partially apply
-- it, e.g.:
--
--- > withFile name = bracket (openFile name) hClose
+-- > withFile name mode = bracket (openFile name mode) hClose
--
+#ifndef __NHC__
bracket
:: IO a -- ^ computation to run first (\"acquire resource\")
-> (a -> IO b) -- ^ computation to run last (\"release resource\")
after a
return r
)
-
+#endif
-- | A specialised variant of 'bracket' with just a computation to run
-- afterward.
'System.IO.openFile'.
-}
-#ifndef __GLASGOW_HASKELL__
+#if !(__GLASGOW_HASKELL__ || __NHC__)
assert :: Bool -> a -> a
assert True x = x
assert False _ = throw (AssertionFailed "")