我写了下面的代码:处理异常
give :: [b] -> Int -> b
give list index = list !! index
现在,我想补充,如果有在点指数的项,它应该显示:“没有项目在那个位置!”
[1..10] `give` 10
No item at that position!
我怎样才能在Haskell
我写了下面的代码:处理异常
give :: [b] -> Int -> b
give list index = list !! index
现在,我想补充,如果有在点指数的项,它应该显示:“没有项目在那个位置!”
[1..10] `give` 10
No item at that position!
我怎样才能在Haskell
你不可能真的。您可以从纯代码中引发异常,但您只能在IO
中捕获异常。
你既可以重新实现give
!!
抛出一个异常根据自己的喜好或者只是选择更稳健的错误处理,像Either
或Maybe
。
的错误处理与Either
一个例子可能是
data OutOfRange = OutOfRange Int
give :: [a] -> Int -> Either OutOfRange a
give xs i | length xs > i = Right $ xs !! i
| otherwise = Left (OutOfRange i)
添加此我想包的返回类型在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
所以Right
和Left
是可用于不同类型的值构造函数,在我们的示例中,为b
和String
(我选择string
为Left
类型,但这不是特别重要)。
根据索引是否成功,此函数返回Either
a String
或b
。它使用模式匹配失败时索引到一个空列表,并使用递归最终模拟!!
。请注意,由于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
使用Either
和Maybe
通常比信号错误,因为它可以让你的代码以正常处理与简单模式匹配Haskell的类型系统中的错误条件更好的主意。
那你试试? –