1

如果内部发生错误,有没有办法不修改 IORef 值modifyIORef

import Data.IORef

main = do
  a <- newIORef (1::Int)

  -- a keeps error now, not Int
  modifyIORef a (const $ error "Error forever")

  val <- readIORef a  -- val is error now
  putStrLn $ "Result: " ++ show val -- throws error
4

2 回答 2

2

我相信您可以使用异常处理程序modifyIORef'atomicModifyIORef'将其包装在异常处理程序中。我一般不会推荐它。error调用产生字符串供用户阅读,而不是处理程序的详细信息。处理从“纯”代码抛出的异常的整个“不精确异常”机制需要非常小心才能正确使用。确保从不从纯代码中抛出异常几乎总是更好。ExceptT等等Either可以提供帮助。

于 2016-05-06T17:27:10.777 回答
-1

Haskell 不像其他语言(如 Python 和 Java)那样进行错误处理。当您调用该error函数时,程序将停止。时期。无法捕获错误。无法重定向它或重新启动程序。该error函数引发错误,而不是异常。如果你想在 Haskell 中表示失败的想法,你可以使用Maybeand Eithermonads。下面是您如何使用Eithermonad 实现您想要的功能。

main = do
  a <- NewIORef (Right 1 :: Either String Int)
  modifyIORef a (const $ Left "some execution error")  
  -- a now holds a "Left" value, representing an error
  val <- readIORef a 
  -- val now holds the "Left" value
  case val of
    Left err -> putStrLn $ "Error: " ++ err -- prints error (if applicable)
    Right val -> putStrLn $ "Result: " ++ show val -- prints value (if applicable)

编辑:正如 dfeuer 在他的评论中指出的那样,可以拦截 GHC 中的错误。但是,除非在非常特殊的情况下,否则它被认为是不好的做法,因此仍然首选使用Maybeand类型。Either

于 2016-05-06T17:17:30.670 回答