【发布时间】:2018-12-04 20:04:17
【问题描述】:
给定斐波那契无限列表
fibo a b = a : fibo b (a+b)
并给出以下两个调用:
foldl (+) 1 (take 1000000 $ fibo 1 1)foldr (+) 1 (take 1000000 $ fibo 1 1)
我预计第一个 (foldl) 会因为 thunk 而分配大量内存,事实上这就是发生的情况。
但是,我没想到第二个会一样。由于 foldr 是如何定义的,我认为对于 (+) 的正确参数(因为它的严格性)会执行一个通常的堆栈之类的评估。
实际上,即使在这种情况下,我也分配了大量内存。
发生了什么?
【问题讨论】:
-
高效完成特定任务的最佳函数是
foldl'。 可能使用foldr有效地做到这一点,但只能以一种有点扭曲的方式:foldr (\x r acc -> r $! x + acc) id (take ...) 1。