假设我有:
import qualified Data.ByteString.Lazy as L
bs1 :: L.ByteString
bs2 :: L.ByteString
L.append bs1 bs2
也懒惰,因为这不会导致我立即消耗所有的bs1吗?与L.concat
类似,与L.length
不同,我理解它会导致它占用整个字节串,因为它需要计算所有字节。
答案 0 :(得分:8)
确定函数的惰性的一种简单方法是传递部分定义的值。例如,让我们定义一个块的延迟字节串,后跟一个未定义的尾部。
*Main> let bs1 = L.fromChunks $ B.pack [102, 111, 111] : undefined
*Main> bs1
Chunk "foo" *** Exception: Prelude.undefined
如您所见,尝试打印它会在第一个块之后引发异常。现在,让我们定义另一个懒惰的ByteString并尝试追加它们。
*Main> let bs2 = L.pack [98, 97, 114]
*Main> L.append bs1 bs2
Chunk "foo" *** Exception: Prelude.undefined
L.append
能够生成生成的惰性ByteString的第一个块。这意味着它只需要查看bs1
的第一个块来生成结果的第一个块,即它就像你期望的那样懒惰。
答案 1 :(得分:1)
是的,追加和连接是懒惰的,他们只会在需要时触摸块。 bs1的第一个块是立即需要的,第二个(如果存在的话)第一个消耗等等。