<div dir="ltr">Data.Functor.Compose:<div><br></div><div>newtype Compose f g a = Compose { getCompose :: f (g a) }</div><div><br></div><div>there's clear-cut, more traditional instances if `f` and `g` are Applicative:</div><div><br></div><div>instance (Applicative f, Applicative g, Semigroup a) => Semigroup (Compose f g a) where</div><div>  (<>) = liftA2 (<>)</div><div><br></div><div>instance (Applicative f, Applicative g, Monoid a) => Monoid (Compose f g a) where</div><div>  mempty = pure mempty</div><div><br></div><div>There's an alternative with `QuantifiedConstraints`, but it's arguable that this is desirable:</div><div><br></div><div>instance (forall x. Semigroup x => Semigroup (f x), forall x. Semigroup x => Semigroup (g x), Semigroup a) => Semigroup (Compose f g a) where</div><div>  Compose x <> Compose y = Compose (x <> y)</div><div><br></div><div>Both to seem to fit the commonplace spirit of lifting monoids up through applicative contexts.</div></div>