我正在编写一个从列表中返回每个元素的程序。列表可以是任何类型。我想在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
答案 0 :(得分:6)
在这种情况下,您可以使用Maybe
或Either
。
这就是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
另一种方法是使用Either
。 Either
将返回Left
或Right
。 Left
将是我们的错误"。
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