简体   繁体   English

如果发生错误,IORef 保持值

[英]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. ExceptTEither等可以提供帮助。

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失败的想法,你使用MaybeEither单子。 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.但是,除非在非常特殊的情况下,否则它被认为是不好的做法,因此仍然首选使用MaybeEither类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM