2011-09-14 118 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