Joe*_*ams 22 haskell fold strictness
Haskell有两个左侧折叠函数用于列表:foldl和"严格"版本foldl'.非严格的问题foldl是它构建了一个thunk的塔:
foldl (+) 0 [1..5]
--> ((((0 + 1) + 2) + 3) + 4) + 5
--> 15
Run Code Online (Sandbox Code Playgroud)
这会浪费内存,如果列表中的项目太多,可能会导致堆栈溢出. foldl'另一方面,强制累加器在每个项目上.
但是,就我所知,foldl'在语义上等同于foldl.评估foldl (+) 0 [1..5]头部正常形式需要在某个时刻强制累加器.如果我们不需要头部正常形式,我们就不会foldl (+) 0 [1..5]开始评估.
有没有令人信服的理由,人们会想要foldl超过那个的行为foldl'?
ham*_*mar 25
foldl并且foldl'在语义上不等同.琐碎的反例:
Prelude Data.List> foldl (\x y -> y) 0 [undefined, 1]
1
Prelude Data.List> foldl' (\x y -> y) 0 [undefined, 1]
*** Exception: Prelude.undefined
Run Code Online (Sandbox Code Playgroud)
然而,在实践中,foldl'由于您提到的原因,您通常需要严格.
Dan*_*her 13
当foldl并且foldl'不会产生相同的结果时,如在hammar的例子中,必须根据期望的结果做出决定.除此之外,你要使用foldl而不是foldl'折叠函数是构造函数(应用构造函数在WHNF中创建一个值,没有必要再次强制它到WHNF),并foldl (.) id functions强迫WHNF也没有获得任何东西.除了这些特殊情况,foldl'是选择的方法.