foldl比其严格的堂兄,foldl'更受欢迎吗?

时间:2011-11-23 00:21:42

标签: haskell fold strictness

Haskell有两个左侧折叠函数用于列表:foldl和“严格”版本foldl'。非严格foldl的问题在于它构建了一个thunk的塔:

    foldl (+) 0 [1..5]
--> ((((0 + 1) + 2) + 3) + 4) + 5
--> 15

这会浪费内存,如果列表中的项目太多,可能会导致堆栈溢出。另一方面,foldl'强制累加器在每个项目上。

但是,据我所知,foldl' 在语义上等效于foldl。评估foldl (+) 0 [1..5]以达到正常形式需要在某个时刻强制累加器。如果我们不需要头部正常形式,我们就不会开始评估foldl (+) 0 [1..5]

是否有任何令人信服的理由要求foldl的行为超过foldl'的行为?

2 个答案:

答案 0 :(得分:25)

foldlfoldl'在语义上不相同。琐碎的反例:

Prelude Data.List> foldl (\x y -> y) 0 [undefined, 1]
1
Prelude Data.List> foldl' (\x y -> y) 0 [undefined, 1]
*** Exception: Prelude.undefined

但是,在实践中,由于您提到的原因,您通常需要严格的foldl'

答案 1 :(得分:13)

foldlfoldl'不会产生相同的结果时,如在hammar的例子中,必须根据所需的结果做出决定。除此之外,如果折叠函数是构造函数,则使用foldl而不是foldl'(应用构造函数在WHNF中创建一个值,再次强制它到WHNF没有意义),并且foldl (.) id functions迫使WHNF也没有获得任何收益。除了这些例外情况,foldl'是首选方法。

相关问题