如何在Haskell代码中报告错误

时间:2018-03-20 01:27:34

标签: haskell

我正在编写一个从列表中返回每个元素的程序。列表可以是任何类型。我想在r为零时报告错误,但是我的代码不能正常工作(当我注释掉错误行时工作正常)。任何人都可以告诉我如何在这种情况下报告错误

rthElem :: Int -> [a] -> [a]
rthElem _ [] = []
rthElem 0 (x:xs) = "Error"
rthElem n (x:xs) = rthElem' n 1 (x:xs) where
    rthElem' n i (x:xs)  = (if (n `divides` i) then
        [x] else
        [])
        ++ (rthElem' n (i+1) xs)
    rthElem' _ _ [] = []
    divides x y = y `mod` x == 0  

3 个答案:

答案 0 :(得分:6)

在这种情况下,您可以使用MaybeEither

这就是Maybe的样子。 Nothing将是我们的错误"。

rthElem :: Int -> [a] -> Maybe [a]
rthElem _ [] = Just []
rthElem 0 (x:xs) = Nothing
rthElem n (x:xs) = Just (rthElem' n 1 (x:xs)) where
    rthElem' n i (x:xs)  = (if (n `divides` i) then
        [x] else
        [])
        ++ (rthElem' n (i+1) xs)
    rthElem' _ _ [] = []
    divides x y = y `mod` x == 0

main :: IO ()
main = case (rthElem 0 [1..5]) of
  Nothing  -> putStrLn "Error"
  Just elm -> print elm

另一种方法是使用EitherEither将返回LeftRightLeft将是我们的错误"。

rthElem :: Int -> [a] -> Either String [a]
rthElem _ [] = Right []
rthElem 0 (x:xs) = Left "Error"
rthElem n (x:xs) = Right (rthElem' n 1 (x:xs)) where
    rthElem' n i (x:xs)  = (if (n `divides` i) then
        [x] else
        [])
        ++ (rthElem' n (i+1) xs)
    rthElem' _ _ [] = []
    divides x y = y `mod` x == 0

main :: IO ()
main = case (rthElem 0 [1..5]) of
  Left err  -> putStrLn err
  Right elm -> print elm

最好的方法是使用Either。阅读有关错误处理here的更多信息。

答案 1 :(得分:4)

如果您确实要打印错误并显示错误,可以使用错误功能error :: String -> a

rthElem 0 (x:xs) = error "Error msg here"

但是有更好的方法可以做到这一点,你应该弄清楚哪一种适合你的情况,你可以使用Maybe,甚至是monad,这里有一个有趣的链接,例子http://www.randomhacks.net/2007/03/10/haskell-8-ways-to-report-errors/

答案 2 :(得分:0)

您可以使用例外,但您还必须将您的功能转换为IO操作。

rthElem :: Int -> [a] -> IO [a]
rthElem _ [] = return []
rthElem 0 _ = ioError $ userError "Error"
rthElem n l = return $ rthElem' n 1 l where
    rthElem' n i (x:xs)  = (if (n `divides` i) then
        [x] else
        [])
        ++ (rthElem' n (i+1) xs)
    rthElem' _ _ [] = []
    divides x y = y `mod` x == 0