Skip to content

fold

The function

fold :: Monoid m => t m -> m

is a specialization of foldMap to containers whose elements are already values of some monoidal type m. Then we don't need to first map the container elements to the monoid before accumulating the elements. Instead, we can accumulate the elements in the container directly, using the monoid multiplication (<>). The default implementation uses foldMap to map every element to itself, using the identity function id, and accumulate the resulting collection of monoid elements:

fold = foldMap id

To try this out, we can exploit that trees are functors, as witnessed by the following Functor instance:

GHCi
>>> :{
  | instance Functor Tree where
  |     fmap f = go
  |       where
  |         go Empty        = Empty
  |         go (Node l x r) = Node (go l) (f x) (go r)
  | :}

We can now turn our tree from before, which is a tree of numbers, into a tree of lists of numbers using fmap singleton tree. Since the values stored in this tree are lists, which form a monoid with list concatenation as the monoid operation, we can collect the elements in the tree into a list using fold $ fmap singleton tree:

GHCi
>>> fold $ fmap singleton tree
[5,3,1,2]

Or we can once again sum or multiply the values in the tree by first using fmap to wrap each tree element in a Sum or Product, folding the resulting tree using Sum or Product's monoid operation, and then extracting the value using getSum or getProduct:

GHCi
>>> getSum $ fold $ fmap Sum tree
11
>>> getProduct $ fold $ fmap Product tree
30

Again, these two uses of Sum and Product are not the most elegant way to achieve our goal here, but they serve to illustrate what we can do using fold.