2014-02-27 37 views
3

鑑於如何重新拋出一般異常哈斯克爾

f :: Int -> IO (Either SomeException Int) 

g = do 
    results <- mapM f [1,2,3] 
    let (errs, succs) = partitionEithers results 
    if null errs then return succs 
       else -- rethrow arbitrary exception 
        throwIO (fromJust . fromException $ head errs) 

我本來期望g重新拋出遇到任何異常,但編譯失敗與ambigous類型的變量。隨機噴灑存在量化助手並沒有幫助。

如何重新拋出我遇到的任意異常而不失去通用性?

回答

3

只需使用throwIO $ head errs

錯誤消息是因爲fromException需要轉到編譯時已知的類型。你不提供它的上下文來找出它是什麼類型,所以它抱怨類型變量是不明確的。

幸運的是,你不需要需要知道它是什麼類型。 SomeException也是Exception的一個實例。它可以在不知道它包含什麼類型的情況下重新生成。實際上,如果你看看Exception類的定義,它只是toExceptionfromException,它們是依靠Typeable來確保它們不會破壞類型系統的轉換函數。 SomeException的實例Exception只是這些最無聊的可能的定義。

+0

確實。但是,現在我在捕獲異常時遇到了模棱兩可的錯誤:'tryJust(Just。toException)'抱怨'異常''e'沒有被修復......但它應該適用於所有'e's,不應該? – ron

+0

哦,它只是修復'e'到'SomeException' .. ..這是非直觀的:) – ron