lan*_*ula 6 haskell lazy-evaluation bytestring
我正在学习 Haskell,但在理解惰性 ByteStrings 的工作原理时遇到了一些困难。Hackage说“Lazy ByteStrings 使用严格块的惰性列表,这使其适用于 I/O 流任务”。相比之下,严格列表存储为一个大数组。
惰性字节串中的这些“块”是什么?你的编译器如何知道一个块应该有多大?此外,我知道惰性列表背后的想法是您不必存储整个事物,因此允许无限列表和所有这些。但是这个存储是如何实现的呢?每个块都有指向下一个块的指针吗?
非常感谢您的帮助:)
你可以在ByteString这里找到懒惰的定义:
data ByteString = Empty | Chunk {-# UNPACK #-} !S.ByteString ByteString
deriving (Typeable)
Run Code Online (Sandbox Code Playgroud)
Chunk一个数据构造函数也是如此- 第一部分是严格的 ( !)严格的( S.)ByteString然后更多Chunks或Empty通过第二个递归(懒惰)ByteString部分。
请注意,第二部分没有(!)那里 - 所以这可以是一个GHC thunk(Haskell 中的懒惰的东西),只有在你需要它时才会被强制执行(例如模式匹配)。
这意味着惰性ByteString是Empty或者你得到一个严格的(如果你愿意,你可以认为它已经加载了)完整字符串的一部分或块,带有惰性剩余/rest/tail ByteString。
至于取决于生成这个惰性字节串的代码的大小 - 编译器没有考虑到这一点。
你可以看到这个hGetContents:
hGetContents = hGetContentsN defaultChunkSize
Run Code Online (Sandbox Code Playgroud)
wheredefaultChunkSize被定义为32 * 1024 - 2 * sizeOf (undefined :: Int)- 所以有点小于32kB
是的,其余的(snd。参数Chunk)可以被视为指向下一个Chunk或Empty(就像普通列表一样)的指针。
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |