【问题标题】:Behaviour of IORef in HaskellHaskell 中 IORef 的行为
【发布时间】:2021-12-17 09:44:10
【问题描述】:

在 GHCI(9.0.1 版)中,以下内容返回了我的预期:

ghci> import Data.IORef
ghci> ref <- newIORef ([] :: [Int])
ghci> modifyIORef ref (1:)
ghci> readIORef ref
[1]

但是当我以这种方式尝试同样的事情时:

ghci> import Data.IORef
ghci> ref = newIORef ([] :: [Int])
ghci> ref >>= \r -> modifyIORef r (1:) 
ghci> ref >>= readIORef
[]

返回一个空列表,就好像修改从未发生过一样。为什么会这样?输出不应该一样吗?

【问题讨论】:

  • 您可能还会发现这些启发式的脱糖。第一个是m &gt;&gt;= (\x -&gt; f x &gt;&gt; g x);后者是(m &gt;&gt;= (\x -&gt; f x)) &gt;&gt; (m &gt;&gt;= (\x -&gt; g x))。注意m 出现一次,每个x 在第一个出现两次,但m 出现两次,每个x 在第二个出现一次。我认为您的演示文稿令人困惑的部分原因在于,在您的第一个示例中,您的 ref 对应于 x,但在您的第二个示例中,您的 ref 对应于 m,因此您为两个选择了相同的名称不同的东西。
  • 该问题与stackoverflow.com/questions/28624408/… 密切相关 请记住ref = newIORef [] 意味着您始终可以将ref 替换为newIORef [],因此最后几行的行为等同于newIORef [] &gt;&gt;= ...

标签: haskell ioref


【解决方案1】:

当你写ref = newIORef ...时,ref的类型是IO (IORef [Int])(因为这是newIORef返回的类型)。每次执行该 IO 操作(通过将其包含在 GHCI 评估的 IO 操作中),您都会获得一个新的 IORef。

相反,当您编写ref &lt;- newIORef 时,您是在要求GHCI 执行IO 操作,产生IORef [Int],并将生成的IORef 保存到变量ref。然后你对它执行的所有后续操作都在同一个 IORef 上执行。

【讨论】:

    猜你喜欢
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    相关资源
    最近更新 更多