这是我之前提出的问题的后续。我想知道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