{-# OPTIONS -fglasgow-exts #-} module MyException where import Prelude hiding (catch) import Data.Dynamic import qualified Control.Exception as Ex class (Typeable x, Show x) => Exception x data ArithException = ArithException Ex.ArithException deriving (Typeable, Show) data IOException = IOException Ex.IOException deriving (Typeable, Show) instance Exception ArithException instance Exception IOException data SomeException = forall x. Exception x => SomeException x deriving Typeable instance Show SomeException where show (SomeException x) = show x throw :: Exception x => x -> a throw x = Ex.throwDyn (SomeException x) matchException :: Exception x => SomeException -> Maybe x matchException (SomeException x) = fromDynamic (toDyn x) catch :: Exception x => IO a -> (x -> IO a) -> IO a catch io h = io `Ex.catchDyn` \e -> case () of _ | Just x <- matchException e -> h x | otherwise -> Ex.throwDyn e test = do x `catch` (\(IOException e) -> print e) `catch` (\(ArithException e) -> print e) x = throw (ArithException Ex.DivideByZero)