混淆IORefs做出反应 [英] Confusion over IORefs to make a counter

查看:156
本文介绍了混淆IORefs做出反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找到了一些示例代码,并将其更改了一些。

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆