Skip to content

foldl1 and foldr1

The two functions

foldl1 :: (a -> a -> a) -> t a -> a
foldr1 :: (a -> a -> a) -> t a -> a

are specialized versions of foldl and foldr for non-empty containers. In this case, if the accumulated value is of the same type as the elements in the container, we can get away without specifying the initial accumulator value. Instead, we take the first or last container element (first for foldl1, last for foldr1) as the initial accumulator value and then use the accumulation function to combine the container elements.

Here are two possible default implementations of these functions, again using lists as an intermediate representation. They are different from the actual implementations, which are more complicated but avoid the detour via lists.

foldl1 f xs = foldl1 f $ foldMap singleton xs
foldr1 f xs = foldr1 f $ foldMap singleton xs

Again, foldMap singleton xs takes care of converting the container to a list. And then we use list-specific versions of foldl1 and foldr1 to accumulate the list elements. We discussed list-specific implementations of foldl1 and foldr1 before.