Использование GADT в обработке исключений - PullRequest
1 голос
/ 15 сентября 2011

Вот моя проблема

Я использую 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?Может ли кто-нибудь дать подсказку, как начать его строить?Учебники, которые я читал, предполагают, что вы пытаетесь решить более сложную проблему, чем у меня.

Если я ошибаюсь, кто-то может указать мне правильное направление?

updateЯ узнал о динамических типах из 1 и вскоре после этого обнаружил Data.Dynamic.Становится теплее?

Веселье с фантомными типами

1 Ответ

3 голосов
/ 15 сентября 2011

Экземпляр «Показать исключения» в основном используется, когда вы сами не обрабатываете исключение, и оно распечатывается в другом месте вашей программы (например, на верхнем уровне). Поскольку вы перехватываете исключения с помощью специального обработчика, вы можете просто поместить 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
...