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?
if x == y then True else acccould be a bit tidier asacc || x == y, imho. - Bartek Banachewiczx == y || acc, undoubtedly. - Will Ness