foldr and foldl applied to addition (using infix notation) Folding foldr and foldl applied to addition (using infix notation)
First some examples Then proofs of the types of foldr and foldl
foldr (+) 0 [2,3,4] foldr (+) 0 [2,3,4] = (recursion) (+) 2 (foldr (+) 0 [3,4]) = (recursion) (+) 2 ( (+) 3 (+) (foldr (+) 0 [4]) ) = (recursion) (+) 2 ( (+) 3 ( (+) (4 (+) (foldr (+) 0 []) ))) = (base) (+) 2 ( (+) 3 ( (+) (4 (+) (0) ))) = (infix notation) This computes (2 + (3 + (4 + 0))) = 9
foldl (+) 0 [2,3,4] foldl (+) 0 [2,3,4] = (recursion) foldl (+) ((+) 0 2) [3,4] = foldl (+) (2 [3,4]) = (recursion) foldl (+) ((+) 2 3) [4]) = foldl (+) (5 [4]) = (recursion) foldl (+) ((+) 5 4) [] = (base) foldl (+) 9 [] = 9 This computes (((0(+)2)(+)3)(+)4) = 9
type of foldl / foldr As applied to (+), both functions have the type:
type of foldl / foldr As applied to (+), both functions have the type: (Int -> Int -> Int) -> (Int -> [Int] -> Int) The lecture notes show that this is a special case. In general, foldr :: (a->b->b) - > b->[a]->b foldl :: (a->b->a) -> a->[b]->a
First foldr, starting from its definition The first question to ask is, what is the type of f More specifically, what’s the type of the outcome of f? (Does this outcome have the same type as f’s 1st argument or the same type as f’s 2nd argument?)
foldr f y (x:xs) = f x (foldr f y xs) R,S,P,Q are types foldr f y [] = y P Q foldr f y (x:xs) = f x (foldr f y xs) ?? [a] a b f :: a b ? ?=b because Q=P=b y :: ?? ??=b because S=P Therefore, foldr :: (abb)b[a]b
Now foldl, starting from its definition foldl f y [] = y P and Q are types foldl f y (x:xs) = foldl f (fyx) xs P Q=a f :: a -> b -> ? Within fyx, the first arg of f is y, so Type(y)=a. P = Q therefore, Type(y)=P=a Therefore (comparing left and right), Type(fyx)=a. Therefore, ?=a Therefore, Type(foldl) = (a->b->a) -> a->[b]->a