2011-09-14 32 views
2

我有三个函数可以映射,我希望在捕获异常时停止评估。 我可以捕捉到异常,但没有得到我想要的行为。这可能是因为我正在以不正确的方式思考这个问题(也许我不应该在这种情况下映射一个函数列表),并且希望这个被指出。以下是我认为的相关代码。一旦我发现异常,我该如何停止评估函数列表

import qualified Control.Exception as C 
data JobException = PreProcessFail 
        | JobFail 
        | ChartFail 
        deriving (Show, Typeable) 

instance C.Exception JobException 



type ProcessState = MVar ProcessConfig 



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

exceptionHandler :: JobException -> IO() 
exceptionHandler exception = do 
    writeFile "testException.txt" ("caught exception " ++ (show exception)) 
-- much more functionality will be put here once I get the logic correct 
preProcess :: ProcessState -> IO() 
preProcess sModel = do 
    putStrLn ("preProcessing") 

initiateJob :: ProcessState -> IO() 
initiateJob sModel = do 
    C.throw JobFail 
    putStrLn ("in progress") 
makeChart :: ProcessState -> IO() 
makeChart sModel = do 
    putStrLn ("chart making") 

所以,现在,当我在ghci中测试这个,这就是发生了什么。

a <- mapM (flip Control.Exception.catch exceptionHandler) [preProcess world, initiateJob world, makeChart world] 
Loading package filepath-1.2.0.0 ... linking ... done. 
Loading package unix-2.4.2.0 ... linking ... done. 
preProcessing 
chart making 

我不应该看到字符串“制图”。抛出异常时如何中止评估列表?

+0

您应该使用代码块格式,而不是该代码的块引用格式。代码块编辑窗口中的符号看起来像'{}',而不是'''。 – rovaughn

回答

4

mapM映射函数然后对列表进行排序。所以你已经分别在列表中的每个动作周围都有一个catch。你想要的是将列表排序为单个动作,然后捕获的一次例外因此中断列表中的其他所有内容。以下工作:

(flip Control.Exception.catch exceptionHandler) $ sequence_ [preProcess world, initiateJob world, makeChart world] 
相关问题