我在Haskell中进行懒惰评估的困难之一是难以推断内存使用情况.我认为复制thunk的能力会让我更容易.这是一个例子.
让我们创建一个非常大的列表:
let xs = [1..10000000]
Run Code Online (Sandbox Code Playgroud)
现在,让我们创建一个不好的函数:
bad = do
print $ foldl1' (+) xs
print $ length xs
Run Code Online (Sandbox Code Playgroud)
没有优化,这会占用几十MB的内存.垃圾收集器在折叠期间不能解除分配xs,因为稍后需要计算长度.
是否有可能重新实现此功能:
good = do
(xs1,xs2) <- copyThunk xs
print $ foldl1' (+) xs1
print $ length xs2
Run Code Online (Sandbox Code Playgroud)
现在,xs1和xs2将表示相同的值,但在内存中也相互独立,因此垃圾收集器可以在折叠期间解除分配以防止内存浪费.(我认为这会稍微增加计算成本吗?)
显然在这个简单的例子中,重构代码可以很容易地解决这个问题,但似乎并不总是很明显如何重构.或者有时重构会大大降低代码清晰度.