This is a follow-up to a question I asked earlier. I am wondering if the way list is updated in IORef
below in the accepted solution is O(1)
or not, in every call of fetch
. I suspect it is because IORef
is likely just keeping a pointer to head of the list (instead of traversing and copying entire list which will be O(n) every time. Just changing the pointer to new head should be O(1), and should prevent eager evaluation of entire list). But, ghc-core
won't show that low-level code. So, asking here:
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