As pierr replied, you should use foldl' . For more information:
foldl' calculates its “left side” before passing it to the fold step.foldr gives your focus the thunk step for the right value. This "thunk" will be calculated when necessary.
Make a sum with foldr and see how it is valued:
foldr (+) 0 [1..3] 1 + foldr (+) 0 [2..3] 1 + 2 + foldr (+) 0 [3] 1 + 2 + 3 + foldl (+) 0 [] -- this is a big thunk.. 1 + 2 + 3 + 0 1 + 2 + 3 1 + 5 6
And with foldl' : (the tag is missing in the code because SO does not display it beautifully)
foldl (+) 0 [1..3] -- seq is a "strictness hint". -- here it means that x is calculated before the foldl x `seq` foldl (+) x [2..3] where x = 0+1 foldl (+) 1 [2..3] x `seq` foldl (+) x [3] where x = 1+2 foldl (+) 3 [3] x `seq` foldl (+) x [] where x = 3+3 foldl (+) 6 [] 6
In good use for foldr that do not leak. The "step" should either:
- Returns a result that is independent of the "right side", ignores it, or contains it in a lazy structure
- Bring back the right side, like
Examples of good use of foldr :
-- in map, the step returns the structure head -- without evaluating the "right-side" map f = foldr ((:) . f) [] filter f = foldr step [] where step x rest = | fx = x : rest -- returns structure head | otherwise = rest -- returns right-side as is any f = foldr step False where -- can use "step x rest = fx || rest". it is the same. -- version below used for verbosity step x rest | fx = True -- ignore right-side | otherwise = rest -- returns right-side as is
source share