There are lots of good questions and answers about foldl
, foldr
, and foldl'
in Haskell.
So now I know that:
1) foldl
is lazy
2) don't use foldl
because it can blow up the stack
3) use foldl'
instead because it is strict (ish)
How foldl
is evaluated:
1) a whole bunch of thunks are created
2) after Haskell is done creating thunks, the thunks are reduced
3) overflow the stack if there are too many thunks
What I'm confused about:
1) why does reduction have to occur after all thunk-ing?
2) why isn't foldl
evaluated just like foldl'
? Is this just an implementation side-effect?
3) from the definition, foldl
looks like it could be evaluated efficiently using tail-recursion -- how can I tell whether a function will actually be efficiently evaluated? It seems like I have to start worrying about order-of-evaluation in Haskell, if I don't want my program to crash.
Thanks in advance. I don't know if my understanding of the evaluation of foldl
is right -- please suggest corrections if necessary.
UPDATE: it looks the answer to my question has something to do with Normal Form, Weak Normal Form, and Head Normal Form, and Haskell's implementation of them.
However, I'm still looking for an example where evaluating the combining function more eagerly would lead to a different result (either a crash or unnecessary evaluation).
The short answer is that in foldl f
, it's not necessarily the case that f
is strict, so it might be too eager to reduce the thunks up front. However, in practice it usually is, so you nearly always want to be using foldl'
.
I wrote a more in-depth explanation of how the evaluation order of foldl
and foldl'
works on another question. It's rather long but I think it should clarify things a bit for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With