[英]IORef keeping value if an error occurs
Is there a way to NOT modify IORef value if error happens inside modifyIORef
?如果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
I believe you can do this with modifyIORef'
or atomicModifyIORef'
wrapped in an exception handler.我相信您可以使用包含在异常处理程序中的modifyIORef'
或atomicModifyIORef'
来做到这一点。 I wouldn't recommend it in general;我一般不会推荐它; error
calls produce strings for users to read, not detailed info for a handler. error
调用会生成供用户阅读的字符串,而不是处理程序的详细信息。 And the whole "imprecise exception" mechanism for handling exceptions thrown from "pure" code requires quite a lot of care to use correctly.用于处理从“纯”代码抛出的异常的整个“不精确异常”机制需要非常小心才能正确使用。 You're almost always better off making sure never to throw exceptions from pure code.确保永远不会从纯代码中抛出异常几乎总是更好。 ExceptT
and Either
and such can help. ExceptT
和Either
等可以提供帮助。
Haskell does not do error handling in the same way that other languages, such as Python and Java, do. Haskell 的错误处理方式与其他语言(例如 Python 和 Java)不同。 When you call the error
function, the program will halt.当您调用error
函数时,程序将停止。 Period.时期。 The error cannot be caught.无法捕捉到错误。 There is no way of redirecting it, or restarting the program.没有办法重定向它,或重新启动程序。 The error
function raises an error, not an exception. error
函数会引发错误,而不是异常。 If you want to represent the idea of failure in Haskell, you use the Maybe
and Either
monads.如果你想表示在Haskell失败的想法,你使用Maybe
和Either
单子。 Below is how you might implement the functionality that you want using the 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)
EDIT: As dfeuer kindly pointed out in his comment, it is possible to intercept errors in GHC.编辑:由于dfeuer好心在他的评论中指出,有可能在GHC拦截错误。 It is, however, considered bad practice except in very specific circumstances, so using the Maybe
and Either
types is still preferred.但是,除非在非常特殊的情况下,否则它被认为是不好的做法,因此仍然首选使用Maybe
和Either
类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.