Proposal: Add Semigroup/Monoid instance to Data.Functor.Compose

David Feuer david.feuer at gmail.com
Fri Nov 30 21:54:53 UTC 2018


The alternate one can be written much more simply with
FlexibleContexts instead of QuantifiedConstraints:

instance Semigroup (f (g a)) => Semigroup (Compose f g a) where
  Compose x <> Compose y = Compose (x <> y)
instance Monoid (f (g a)) => Monoid (Compose f g a) where
  mempty = Compose mempty

That strikes me as the most natural way to do it. The lifting
instances are more naturally done using this oft-proposed type:

newtype Ap f a = Ap (f a)
instance (Applicative f, Semigroup a) => Semigroup (Ap f a) where
  Ap x <> Ap y = Ap (liftA2 (<>) x y)
instance (Applicative f, Monoid a) => Monoid (Ap f a) where
  mempty = pure mempty

Now Ap (Compose f g) a will do the lifting you want.

On Fri, Nov 30, 2018 at 4:13 PM Daniel Cartwright <chessai1996 at gmail.com> wrote:
>
> Data.Functor.Compose:
>
> newtype Compose f g a = Compose { getCompose :: f (g a) }
>
> there's clear-cut, more traditional instances if `f` and `g` are Applicative:
>
> instance (Applicative f, Applicative g, Semigroup a) => Semigroup (Compose f g a) where
>   (<>) = liftA2 (<>)
>
> instance (Applicative f, Applicative g, Monoid a) => Monoid (Compose f g a) where
>   mempty = pure mempty
>
> There's an alternative with `QuantifiedConstraints`, but it's arguable that this is desirable:
>
> instance (forall x. Semigroup x => Semigroup (f x), forall x. Semigroup x => Semigroup (g x), Semigroup a) => Semigroup (Compose f g a) where
>   Compose x <> Compose y = Compose (x <> y)
>
> Both to seem to fit the commonplace spirit of lifting monoids up through applicative contexts.
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


More information about the Libraries mailing list