Understand foldr and foldl with examples in Haskell
dropWhileEnd::(a -> Bool) -> [a] -> [a]
dropWhileEnd f = foldr(\x sx -> f x && null sx then [] else x:sx) []


Remove whitespace at the beginning of string
dropW::(a -> Bool) -> [a] -> [a]
dropW f cx = reverse \$ foldl(\xs x -> if (null xs && f x) then [] else x:xs) [] cx


1. foldr(-) 4 [1, 2, 3]

2. [1] is equavalent to following:
foldr(\x -> x - 4) [1, 2, 3]

3. foldr => what does 'r' mean here?
It means: The list is folded from Right side

4. The order of x and 4 are important.
(x - 4) it NOT equal (4 - x)

5. Remember "The list is folded from Right side"
foldr(\x -> x - 4) [1, 2, 3]
= (1 - (2 - (3 - 4)))  -- x = 3
= (1 - (2 - (-1)))     -- x = 2
= (1 - 3)              -- x = 1
= -2

1. foldl(-) 4 [1, 2, 3]

2. (1) is equavalent to following:
foldl(\x -> 4 - x) 4 [1, 2, 3]

3. Remember "The list is folded from LEFT side, fold[l]"
foldl(\x -> 4 - x) 4 [1, 2, 3]
= (((1 - 4) - 2) - 3) -- x = 1
= ((-3 - 2) - 3)      -- x = 2
= ((-5) - 3)          -- x = 3
= -8


reverse = foldl(\x y -> y:x) [] ["a", "b", "c"]
= ["c", "b", "a"]

reverse = foldr(\x y -> y ++ [x]) [] ["a", "b", "c"]
= ["c", "b", "a"]

-- remove tailing space
-- "ab " => "ab"
foldr(\x y -> if x == ' ' then [] else x:y) [] "ab " => "ab"


Make your own foldL and foldR
foldR::(a -> a -> a) -> a -> [a] -> a
foldR f z [] = z
foldR f z (x:cx) = f z (fold f z cx)

-- TODO check it

foldL::(a -> a -> a) -> a -> [a] -> a
foldL f z [] = z
foldL f z cx = f x' (fold f z cx')
where
x' = last cx
cx' = init cx

-- TODO check it



Picture is worth a thousand words