Consider the following signature of foldMap
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
This is very
When a container is Foldable, there is a relationship between foldMap and Applicative (which is a superclass of Monad).
Foldable has a function called traverse_, with signature:
traverse_ :: Applicative f => (a -> f b) -> t a -> f ()
One possible Applicative is Constant. To be an Applicative, it requires the "accumulator" parameter to be a Monoid:
newtype Constant a b = Constant { getConstant :: a } -- no b value at the term level!
Monoid a => Applicative (Constant a)
for example:
gchi> Constant (Sum 1) <*> Constant (Sum 2) :: Constant (Sum Int) whatever
Constant (Sum {getSum = 3})
We can define foldMap in terms of traverse_ and Constant this way:
foldMap' :: (Monoid m, Foldable t) => (a -> m) -> t a -> m
foldMap' f = getConstant . traverse_ (Constant . f)
We use traverse_ to go through the container, accumulating values with Constant, and then we use getConstant to get rid of the newtype.