2010-09-05 127 views
10
foldl1 (+) [] 

如何捕獲由此產生的錯誤?Haskell異常處理如何工作?

+2

另請參閱http://stackoverflow.com/questions/3642793/why-can-haskell-exceptions-only-be-caught-inside-the-io-monad – 2010-09-05 23:48:29

+0

它並不重要,它只是一個問題在安全故障庫接管世界之前的時間;-)。 – 2010-09-06 00:32:59

+0

什麼安全故障庫? – qrest 2010-09-06 05:54:31

回答

14

純代碼可以拋出異步,imprecise exceptions,例如,當一個局部函數遇到輸入它沒有的情況下進行處理。

這些是邏輯錯誤,通常表示程序規範中的錯誤。

它們可能通過exception handler被IO代碼捕獲(通常位於程序的外層)。

例如,要趕上你丟失的情況下空單,

{-# LANGUAGE ScopedTypeVariables #-} 
{-# LANGUAGE BangPatterns  #-} 

import Control.Exception 

main = do 
    handle (\(e :: SomeException) -> print $ "This program as a bug: " ++ show e) $ do 
     let !v = foldl1 (+) ([] :: [Int]) 
     return() 

我們可以觀察到的異常被捕獲,並且程序終止。

$ ./A 
"This program as a bug: Prelude.foldl1: empty list" 
+4

我覺得這個程序也是一個bug,在它的異常安特勒:-) – 2010-09-06 12:20:29

+4

這個程序不是管道。 – 2010-09-06 14:34:42

+0

這次交流給我帶來了很多的樂趣。 – sclv 2010-09-07 23:10:17

4

民粹答案:結果是未定義的(具體地,bottom)。如果以任何方式使用該值來構建程序結果,則不會對其進行任何操作。請參閱Haskell 98 Report section 3.1。它指定這種「錯誤導致程序立即終止並且不能被用戶捕獲」。

最好先檢查輸入值並處理它們,然後才能得到這個結果。如果列表可以包含0個元素,請不要使用fold1。

但實際上,在使用GHC時,您可以使用其他答案中的方法在IO中捕獲它。異常無法在純(非IO)代碼中捕獲,因爲引發異常是控制流程中的變化,這是一種副作用,而不是純粹的計算。