假设我们有以下内容:
l = map f (map g [1..100])
我们想做:
head l
所以我们得到:
head (map f (map g [1..100]))
现在,我们必须得到第一个元素。 map
定义如下:
map f l = f (head l) : (map f (tail l))
然后我们得到:
f (head (map g [1..100]))
然后再次申请:
f (g (head [1..100]))
结果是
f (g 1)
由于懒惰,没有形成中间名单。
这种分析是否正确?并且使用这样的简单结构:
foldl' ... $ map f1 $ map f2 $ createlist
是有史以来创建的中间列表,即使没有“列表融合”? (我认为懒惰应该琐碎地消除它们。)
我唯一可以看到保留清单的理由就是:
l' = [1..100]
l = map f (map g l')
如果在其他地方使用,我们可能希望保留l'
。但是,在上面的l'
情况下,编译器要快速重新计算上面的列表而不是存储它应该是相当简单的。
答案 0 :(得分:7)
在map
示例中,列表单元格已创建,然后立即进行垃圾回收。使用列表融合时,不需要GC或thunk操作(它们都不是免费的)。
答案 1 :(得分:7)
当中间数据结构昂贵时,融合最有利。当传递的结构是惰性的并且以顺序方式访问时,结构可能相对便宜(如列表的情况)。
因此,对于严格的阵列和类似的结构,最大的好处是。然而,由于数据局部性增加,即使融合懒惰列表仍然是一个胜利,因为更少的中间结构被分配为thunk。