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

Fun fact about foldl, foldr
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


When are the foldr and foldl same? When the binary operation is commutive.
  // Equal
  foldl (+) 0 [1, 2, 3]
  foldr (+) 0 [1, 2, 3]

  // Not equal
  foldl (-) 0 [1, 2, 3]
  foldr (-) 0 [1, 2, 3]
Picture is worth a thousand words