module Data.OpenWitness.Exception ( Exn, unsafeExnFromString, throw, catch ) where { import Data.OpenWitness; import Data.Witness; import Data.Maybe; import Data.Typeable; import Control.Exception (throwDyn,catchDyn); import Prelude(IO,String); -- | A key to match exceptions. The type variable is the data the exception carries. ; type Exn = IOWitness; newtype ExnException = MkExnException (Any Exn); -- | In the absence of open witness declarations, an unsafe hack to generate 'Exn' exception keys. -- This is safe if you use a different string each time (and 'hashString' doesn't collide), and if @e@ is a single type. ; unsafeExnFromString :: String -> Exn e; unsafeExnFromString = unsafeIOWitnessFromString; instance Typeable ExnException where { typeOf _ = mkTyConApp (mkTyCon "Data.OpenWitness.Exception.ExnException") []; }; throw :: Exn e -> e -> a; throw exn e = throwDyn (MkExnException (MkAny exn e)); catch :: IO a -> Exn e -> (e -> IO a) -> IO a; catch foo exn catcher = catchDyn foo (\ex@(MkExnException cell) -> case matchAny exn cell of { Just e -> catcher e; _ -> throwDyn ex; }); }