Foldable, Monoid and Monad

后端 未结 3 1709
你的背包
你的背包 2020-12-24 06:58

Consider the following signature of foldMap

foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m

This is very

3条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-24 07:13

    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.

提交回复
热议问题