haskellfoldable

What does the type foldMap :: (Monoid m) => (a -> m) -> f a -> m mean and how to implement it?


Can someone explain what the type mean and how to implement this?

class Foldable f where
  foldMap :: (Monoid m) => (a -> m) -> f a -> m

Based on https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Foldable.html#v:foldMap, they explained it as "Map each element of the structure to a monoid, and combine the results." but I don't quite understand what it means. How can I map an element to the structure of a Monoid?

I tried foldMap f = mconcat . (<$>) f but I got this error:

 • Couldn't match type ‘f’ with ‘[]’
      ‘f’ is a rigid type variable bound by
        the class declaration for ‘Foldable’
        at traversable.hs:41:16
      Expected type: f a -> m
        Actual type: [a] -> m
    • In the expression: mconcat . (<$>) f
      In an equation for ‘foldMap’: foldMap f = mconcat . (<$>) f
    • Relevant bindings include
        foldMap :: (a -> m) -> f a -> m (bound at traversable.hs:45:3)

I tried @WillemVanOnsem's code and got this error:

error:
    • Could not deduce (Data.Foldable.Foldable f)
        arising from a use of ‘foldr’
      from the context: Foldable f
        bound by the class declaration for ‘Foldable’
        at traversable.hs:41:7-14
      or from: Monoid m
        bound by the type signature for:
                   foldMap :: forall m a. Monoid m => (a -> m) -> f a -> m
        at traversable.hs:42:14-47
      Possible fix:
        add (Data.Foldable.Foldable f) to the context of
          the type signature for:
            foldMap :: forall m a. Monoid m => (a -> m) -> f a -> m
          or the class declaration for ‘Foldable’
    • In the expression: foldr (\ x -> mappend (f x)) mempty
      In an equation for ‘foldMap’:
          foldMap f = foldr (\ x -> mappend (f x)) mempty

Solution

  • they explained it as "Map each element of the structure to a monoid, and combine the results." but I don't quite understand what it means. How can I map an element to the structure of a Monoid?

    We do that with the function with signature a -> m. So we define the "mapping" function ourself.

    A monoid [wiki] is an algebraic structure. It is in essence a 3-tuple (S, ⊕, s0) where S is the set of values, ⊕ :: S × S → S is an associative binary operator, and s0 is an identity element, such that s0 ⊕ s = s ⊕ s0 = s.

    Types that are members of the Foldable class are data structures that can be "folded". It means that if you for example have a Tree that contains Ints, so a Tree Int, such that you, for a function f :: Int -> Int -> Int, and a neutral element z, you can derive an Int.

    By using foldMap we will call a function f :: a -> m on these elements, and use the monoid function to "fold" the values. For data structures that implement Functor as well, it is thus, more or less equivalent to foldMap f = foldr mappend mempty . fmap f.

    We can however use the f in the foldr function itself, like:

    foldMap' :: (Foldable f, Monoid m) => (a -> m) -> f a -> m
    foldMap' f x = foldr (\y -> mappend (f y)) mempty x
    

    or shorter:

    foldMap' :: (Foldable f, Monoid m) => (a -> m) -> f a -> m
    foldMap' f = foldr (mappend . f) mempty
    

    Here we thus first pre-process the values in the datastructure with f to convert these to a monoid object, and we call mappend as folding function on these items.