What I've understood about foldl vs. foldr on lists :
If we right fold [0,1,2,3] with a function s and a starting accumulator a, we are doing this :
f 0 (f 1 (f 2 (f 3 a)))
If we left fold [0,1,2,3] with a function s and a starting accumulator a, we are doing this :
f (f (f (f 0 a) 1) 2) 3)
Given :
elem_r :: (Eq a) => a -> [a] -> Bool
elem_r y ys = foldr (\x acc -> if x == y then True else acc) False ys
and
elem_l :: (Eq a) => a -> [a] -> Bool
elem_l y ys = foldl (\acc x -> if x == y then True else acc) False ys
It seems clear to me that elem_r 3 [0..]
will compute what it really must, and return True as soon as value 3 is reached.
f 0 (f 1 (f 2 (f 3 (...)))
Whereas elem_l 3 [0..]
need to evaluate the complete nested functions application before returning a result.
f (f (f (f (f 0 3) 1) 2) 3) ...)
Now my question is :
In the specific case of elem_l 0 [0..]
The searched element is the first item of the list.
In this expression :
f (f (f (f (f 0 0) 1) 2) 3) ...)
The innermost function (f 0 0) can immediately be evaluated to "True".
Why does Haskell continue to evaluate the rest of nested functions?
Even if you "immediately" reduce f 0 0
to True
, that does not help. You still have all the surrounding occurrences of f
to reduce ...
Because f (f (f (f (f 0 0) 1) 2) 3) ...)
is not right. The final parenthesis and the first f
are mismatched, and the initial argument is all wrong. It really is
(f ... (f (f (f (f False 0) 1) 2) 3) ...)
so after foldl
has finished building this expression (which is, never), we have to get through an infinite amount of nested expressions, evaluating them first, before we get to the innermost expression, which gets evaluated last (because f
stops on 0). Or in this case, never.
And the other test, searching for 3, would stop earlier, on (f (f (f (f False 0) 1) 2) 3)
, because now f
stops on 3; but still it'd have to go through the infinite amount of nested expressions first, after that infinite nested expression is built.
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