不,它不是副本。在 Haskell 中,没有“副本”之类的东西,只有值,所有值都是不可变的。
AnIORef
包含一个值。它IORef
本身是可变的:您可以更改它包含的值。值本身是不可变的。要理解这一点,请考虑IORef Int
当前包含5
. 如果您取出该值并将其添加一个以使6
您创建了一个新值,但您并没有将5
值更改为突然变为6
,因为 的值5
是不可变的。
同样,如果我Map
使用该值创建 afromList [("foo", 5), ("bar, 6")]
并将其放入 IORef 中,IORef 现在包含该值,但该值本身是不可变的。如果我取出值并添加一个新条目,我创建了一个新值,而不是修改原始值,与上述和上面Map.insert
的方式完全相同。5
6
希望这能回答你的问题。但是,您现在可能有另一个。如果所有值都是不可变的,那么 IORefs 怎么会改变呢?
答案是 IORef 本身不会改变。然而,IORef 是作为一种通往我们称之为“真实世界”的可变的、不断变化的混乱的门户而存在的。在真实世界中,你可以做同样的事情两次,得到不同的结果。这包括readLine
和readIORef
。IO monad 的存在是为了隔离这种混乱,同时仍然允许程序与之交互。因此,与 IORefs 一起工作的每个函数都在 IO monad 中。