混淆IORefs做出反应 [英] Confusion over IORefs to make a counter
问题描述
我找到了一些示例代码,并将其更改了一些。
counter = unsafePerform $ newIORef 0
newNode _ = unsafePerformIO $
do
i< - readIORef计数器
writeIORef计数器(i + 1)
返回值i
每次运行时返回1然后是2然后是3然后是3等。
但是当我将它改为
newNode = unsafePerformIO $
do
i < - readIORef计数器
writeIORef计数器(i + 1)
返回i
然后我每次运行它时都会得到0 。
为什么会发生这种情况,我该如何解决它? >
在你的第二个版本中, newNode
是一个简单的值,而不是函数。因此,haskell只评估一次,然后在您访问 newNode
时为您提供评估结果。
的警告:除了你知道透明透明的IO操作以外的任何其他操作,使用 unsafePerformIO
是危险的。它可能会与一些优化进行很糟糕的交互,并且通常不会像您期望的那样行事。有一个原因,它的名字中包含unsafe这个词。
作为一种玩弄 unsafePerformIO
你的代码很好,但如果你想用实际代码来使用它,我强烈建议你重新考虑一下。
I found some sample code, and changed it a little
counter = unsafePerform $ newIORef 0
newNode _ = unsafePerformIO $
do
i <- readIORef counter
writeIORef counter (i+1)
return i
Which returns 1 then 2 then 3 then 3 etc each time it's run.
But when I change it to
newNode = unsafePerformIO $
do
i <- readIORef counter
writeIORef counter (i+1)
return i
then I get 0 every time I run it.
Why is this happening, and what can I do to fix it?
In your second version newNode
is a simple value, not a function. So haskell evaluates it exactly once and then gives you the result of that evaluation whenever you access newNode
.
A word of warning: Using unsafePerformIO
on anything other than an IO action which you know to be referentially transparent is dangerous. It might interact badly with some optimizations and just generally not behave like you expect. There's a reason it's got the word "unsafe" in its name.
As a way to play around with unsafePerformIO
your code is fine, but if you ever want to use something like it in real code, I'd strongly encourage you to reconsider.
这篇关于混淆IORefs做出反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!