如何检查函数是返回常规值还是调用错误?

时间:2013-04-30 08:54:32

标签: function haskell error-handling

我得到了一些代码:

setA :: Integer -> Integer
setA 3 = 5
setA 5 = 6
setA 7 = error "some error one"
setA _ = error "some error two"

现在我尝试编写另一个函数

checkError :: Integer -> Bool
checkError x = if HERE_TO_CHECK_IF setA x RETURNS some error two
                then False
                else True

但我怎么能这样做?

由于

4 个答案:

答案 0 :(得分:6)

正如其他答案所述,您应该避免使用error而是使用

setA :: Integer -> Either String Integer
setA 3 = Right 5
setA 5 = Right 6
setA 7 = Left "some error one"
setA _ = Left "some error two"

checkError :: Either String Integer -> Bool
checkError (Left _)  = False
checkError (Right _) = True

但如果你不能这样做,请the source codespoon package查看教授的要求。这很蠢。

然后你可以说

checkError :: Integer -> Bool
checkError x = case teaspoon x of
    Nothing -> False
    Just _  -> True

答案 1 :(得分:3)

据我了解,error调用并不打算被调用者捕获 - 如果你想让错误可以恢复,setA函数应该使用其他一些机制(比如{{ 1}})。如果你坚持要抓住Either,你可以在IO monad中这样做,请参阅this related question

答案 2 :(得分:2)

您的setA功能不正确。如果您希望函数能够返回错误值,则应使用Either

setA :: Integer -> Either String Integer
setA 3 = Right 5
setA 5 = Right 6
setA 7 = Left "some error one"
setA _ = Left "some error two"

检查错误很简单:

checkError :: Either String Integer -> Bool
checkError = either (const True) (const False)

答案 3 :(得分:1)

虽然error只应用于unrecoverable bad state(因此无需捕获),但这是一个捕获错误调用的确切示例

但我认为这不是编写调试器的方法:

{-# LANGUAGE ScopedTypeVariables #-}
import Prelude hiding (catch)
import Control.Exception

setA :: Integer -> Integer
setA 3 = 5
setA 5 = 6
setA 7 = error "some error one"
setA _ = error "some error two"

main = do
  (print $ setA 9)
  `catch` (\(ErrorCall msg) -> putStrLn $ "I caught you, ErrorCall: " ++ msg)
  `catch` (\(exc::SomeException) -> putStrLn $ "Other exception: " ++ show exc)

对于正常编程,使用类型Either包装可能的错误结果,正如其他答案所解释的那样。