2011-09-14 166 views
1

使用GADT這裏是我的問題在異常處理

我使用Control.Exception.catch我的異常處理,它有以下類型: (從Hoogle撲殺)

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

這裏我會被傳遞給我的處理函數

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

> instance Control.Exception JobException 

這裏的構造函數是處理函數,因爲它是現在:

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

我打算用它來做一些日誌記錄。我需要登錄的信息將是一種記錄 JobState

> type JobState = MVar ProcessConfig 

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

所以,因爲我需要一個被迫有我上面提到的類型的處理程序,我需要一個JobState,我想答案會要重寫JobException以隱藏其中的JobState。這似乎是GADT的工作!我不確定,這是新的領域。

我對不對?我可以用GADT解決這個問題嗎? 有人可以提供關於如何開始構建一個線索?我一直在閱讀的教程假設你正試圖解決比我所得到的更復雜的問題。

如果我錯了,有人能指出我的方向是正確的嗎?

更新:我從1瞭解到動態類型,此後不久發現Data.Dynamic。 變暖了嗎?

Fun With Phantom Types

+2

爲什麼你就不能在該異常的JobState?爲什麼選擇GADT? – augustss

+0

現在我設置JobException的方式是拋出異常的函數只會拋出PreProcessFail或JobFail或ChartFail。我需要一些方法來包含例如JobFail和JobState。難以想象如何用標準類型來做到這一點。閱讀幻影類型樂趣後,它看起來就是我想要去的方式。你能給我一個你的意思嗎? –

+0

當我嘗試在JobException中包含JobState時,我收到有關JobState的Show不存在的實例的投訴。我不知道如何編寫該實例,看到JobState是MVar。 –

回答

3

異常的顯示實例主要是用來當你沒有自己處理的異常,它就會在你的程序打印其他地方(例如,在頂層)。由於您使用自定義處理程序捕捉異常,因此應該只能將JobState置於異常,併爲其提供一個簡單的Show實例。

例如:

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