2014-05-05 238 views
0

我寫了下面的代碼:處理異常

give :: [b] -> Int -> b 
give list index = list !! index 

現在,我想補充,如果有在點指數的項,它應該顯示:「沒有項目在那個位置!」

[1..10] `give` 10 
No item at that position! 

我怎樣才能在Haskell

+2

那你試試? –

回答

2

你不可能真的。您可以從純代碼中引發異常,但您只能在IO中捕獲異常。

你既可以重新實現give!!拋出一個異常根據自己的喜好或者只是選擇更穩健的錯誤處理,像EitherMaybe

的錯誤處理與Either一個例子可能是

data OutOfRange = OutOfRange Int 

give :: [a] -> Int -> Either OutOfRange a 
give xs i | length xs > i = Right $ xs !! i 
      | otherwise  = Left (OutOfRange i) 
0

添加此我想包的返回類型在Either值是這樣的:

give :: [b] -> Int -> Either String b 
give [] _ = Left "No item at that position!" 
give (x:xs) index | index == 0 = Right x 
        | otherwise = give xs $ index - 1 

Either是數據的構造,其聲明理論上是這樣的:

data Either a b = Left a | Right b 

所以RightLeft是可用於不同類型的值構造函數,在我們的示例中,爲bString(我選擇stringLeft類型,但這不是特別重要)。

根據索引是否成功,此函數返回Either a Stringb。它使用模式匹配失敗時索引到一個空列表,並使用遞歸最終模擬!!。請注意,由於Haskell類型系統的嚴格性,您不能使用此結果,因爲它僅僅是b類型:您必須明確處理它作爲String的可能性。這裏有一個例子:

case (give [1..10] 10) of 
    (Left s) -> putStrLn $ "Error" ++ s         --String case 
    (Right i) -> putStrLn $ "The value you requested is " ++ show $ i --Int case 

使用EitherMaybe通常比信號錯誤,因爲它可以讓你的代碼以正常處理與簡單模式匹配Haskell的類型系統中的錯誤條件更好的主意。