如果在modifyIORef
内发生错误,有没有办法不修改IORef值?
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
答案 0 :(得分:2)
我相信您可以使用包含在异常处理程序中的modifyIORef'
或atomicModifyIORef'
来执行此操作。我不会一般地推荐它; error
调用生成供用户读取的字符串,而不是处理程序的详细信息。并且处理从“纯”代码抛出的异常的整个“不精确异常”机制需要非常谨慎才能正确使用。你几乎总是更好,确保永远不会从纯代码中抛出异常。 ExceptT
和Either
等可以提供帮助。
答案 1 :(得分:-1)
Haskell不像其他语言(如Python和Java)那样进行错误处理。当您调用error
函数时,程序将暂停。期。无法捕获错误。无法重定向或重新启动程序。 error
函数引发错误,而不是异常。如果您想在Haskell中表示失败的想法,请使用Maybe
和Either
monad。以下是使用Either
monad实现所需功能的方法。
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中的错误。但是,除非在非常具体的情况下,否则将其视为不良做法,因此仍然需要使用Maybe
和Either
类型。