The throwIO variant should be used in preference to throw to raise an exception within the IO monad because it guarantees ordering with respect to other IO operations, whereas throw does not.
读完之后我还是一头雾水。有没有一个例子表明 throw 会导致问题而 throwIO 不会?
附加问题:
以下陈述是否正确?
throw
用于在 IO 中抛出异常,则不保证异常的顺序。 throw
用于在非IO值中抛出异常,则保证异常的顺序。 如果我需要在 Monad Transformer 中抛出异常,我必须使用
throw
而不是 throwIO
,是否保证异常的顺序?
最佳答案
我认为文档可以改进。 throw
需要注意的问题之类的就是throw
返回评估时“爆炸”(引发异常)的底部值;但是由于懒惰,很难控制是否以及何时进行评估。
例如:
Prelude Control.Exception> let f n = if odd n then throw Underflow else True
Prelude Control.Exception> snd (f 1, putStrLn "this is fine")
this is fine
这可以说是你想要发生的事情,但通常不是。例如而不是上面的元组,您最终可能会得到一个带有单个爆炸元素的大数据结构,这会导致在您的 Web 服务器向用户返回 200 或其他内容后引发异常。
throwIO
允许您按顺序引发异常,就像它是另一个 IO 操作一样,因此可以严格控制它:Prelude Control.Exception> throwIO Underflow >> putStrLn "this is fine"
*** Exception: arithmetic underflow
...就像做
print 1 >> print 2
.但请注意,您实际上可以替换
throwIO
与 throw
, 例如:Prelude Control.Exception> throw Underflow >> putStrLn "this is fine"
*** Exception: arithmetic underflow
从现在开始,爆炸值的类型为
IO a
.我实际上并不清楚为什么 throwIO
除了记录成语之外,还存在。也许其他人可以回答这个问题。作为最后一个示例,这与我的第一个示例具有相同的问题:
Prelude Control.Exception> return (throw Underflow) >> putStrLn "this is fine"
this is fine
关于haskell - throw 和 throwIO 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53999720/