Consider a single-linked list. It looks something like
data List x = Node x (List x) | End
It is natural to define a folding function such
A fold replaces every constructor with a function.
For example, foldr cons nil
replaces every (:)
with cons
and []
with nil
:
foldr cons nil ((:) 1 ((:) 2 [])) = cons 1 (cons 2 nil)
For a tree, foldTree branch leaf
replaces every Branch
with branch
and every Leaf
with leaf
:
foldTree branch leaf (Branch (Branch (Leaf 1) (Leaf 2)) (Leaf 3))
= branch (branch (leaf 1) (leaf 2)) (leaf 2)
This is why every fold accepts arguments that have the exact same type as the constructors:
foldr :: (a -> list -> list) -> list -> [a] -> list
foldTree :: (tree -> tree -> tree) -> (a -> tree) -> Tree a -> tree