首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列表的IORef处理

列表的IORef处理
EN

Stack Overflow用户
提问于 2016-06-05 17:11:22
回答 1查看 288关注 0票数 1

这是我之前问过的一个question的后续。我想知道在下面的IORef中更新的方式列表在接受的解决方案中是否是O(1),在fetch的每个调用中都是这样。我怀疑这是因为IORef可能只是保留一个指向列表头的指针(而不是每次遍历和复制整个列表,即O(n) )。只是改变指针到新的头部应该是O(1),并应防止急于评估整个列表)。但是,ghc-core不会显示低级别的代码。所以,在这里问:

代码语言:javascript
复制
mklstream :: L.ByteString -> (IO S.ByteString -> IO r) -> IO r
mklstream lbs sink = do
  ref <- newIORef (L.toChunks lbs)
  let fetch :: IO S.ByteString
      fetch = do chunks <- readIORef ref
                 case chunks of
                   [] -> return S.empty
                   (c:cs) -> do writeIORef ref cs
                                return c
  sink fetch
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-05 17:48:51

是的,在GHC中是O(1)。从IORef中读取和写入的内容与实现中的其他所有元素作为数据表示使用的指针完全相同。实际上,您可以从writeIORef的类型中了解到,它对其数据没有什么特殊的作用:

代码语言:javascript
复制
writeIORef :: IORef a -> a -> IO ()

因为a是完全不受约束的,所以writeIORef不能检查数据,特别是不能遍历传递给它的任何列表。(这并不完全令人信服--运行时可以做它喜欢的任何事情,即使是不受约束的类型,而且您可能相信writeIORef是一个运行时原语--但在这种情况下,事实证明是正确的。)

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37644620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档