简体   繁体   中英

Using GADT in exception handling

Here's my problem

I'm using Control.Exception.catch for my exception handling, which has the following type: (culled from Hoogle)

catchSource
:: Exception e   
=> IO a 
The computation to run
-> (e -> IO a)  
Handler to invoke if an exception is raised
-> IO a  

Here is the constructor I will be passing to my handler function

> data JobException = PreProcessFail
>                   | JobFail
>                   | ChartFail
>                       deriving (Show, Typeable)

> instance Control.Exception JobException

Here is the Handler function as it is right now :

> exceptionHandler :: JobException -> IO ()
> exceptionHandler exception = do
>    writeFile "testException.txt" ("caught exception " ++ show exception )

I'm going to use this to do some logging. The information I need to log will be in a record of type JobState

> type JobState = MVar ProcessConfig

> data ProcessConfig = PConfig { model :: ServerModel
>                              , ipAddress :: String
>                              , cookie :: Cookie
>                              } deriving Show

So since I need a handler that is forced to have the type I mentioned above, and I need a JobState, I thought the answer would be to rewrite JobException to hide a JobState inside it. That seems to be a job for GADT! I'm not sure, this is new territory.

Am I right? Can I solve this with a GADT? Could someone provide a clue in how to begin to construct one? The tutorials I have been reading assume you're trying to solve a more complicated problem than what I have got.

If I am wrong, could someone point me in the right direction?

update: I learned about dynamic types from 1 and found shortly thereafter Data.Dynamic. Getting warmer?

Fun With Phantom Types

The Show instance of exceptions is mainly used when you don't handle an exception yourself and it gets printed out somewhere else in your program (eg, at the top level). Since you're catching the exceptions with a custom handler, you should be able to just put JobState in the exception and give it a trivial Show instance .

For example:

data JobState = JobSuccess | JobFail deriving Show 
newtype JobException = JobException (MVar JobState) deriving Typeable
instance Show JobException where
    show _ = "JobException"
instance Exception JobException

exceptionHandler :: JobException -> IO ()
exceptionHandler (JobException m) = takeMVar m >>= print

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM