处理haskell中的异常

时间:2014-05-05 22:22:49

标签: list exception haskell

我写下面的代码:

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

现在我要补充一点,如果点索引处没有项目,则应显示:“该位置没有项目!”

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

如何在haskell中添加此内容

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分: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一个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类型系统中的错误条件。