IORef处理清单

时间:2016-06-05 17:11:22

标签: haskell time-complexity ioref

这是我之前提到的question的后续行动。我想知道,在IORef的每次通话中,接受的解决方案中下面O(1)中的路径列表是否更新fetch。我怀疑是因为IORef可能只是保持指向列表头部的指针(而不是遍历和复制整个列表,每次都是O(n)。只需将指针更改为新头应为O( 1),并应防止对整个列表进行急切评估)。但是,ghc-core不会显示低级代码。所以,问这里:

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

1 个答案:

答案 0 :(得分:7)

是的,在GHC中它是O(1)。从IORef读取和写入的内容与实现中的其他所有内容都用作数据表示的指针完全相同。实际上,您只能从writeIORef的类型中知道它对数据没有什么特别之处:

writeIORef :: IORef a -> a -> IO ()

由于a完全不受约束,writeIORef 无法检查数据,特别是无法遍历您提交的任何列表。 (这不太令人信服 - 即使使用无约束类型,运行时也可以执行它喜欢的任何操作,并且您可能认为writeIORef是运行时原语 - 但无论如何在这种情况下都证明它是真的。)< / p>