2014-05-05 243 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的类型系统中的错误条件更好的主意。