There are monads for which you want another Monoid, e.g. Maybe provides a different unit, because it pretends to lift a Semigroup into a Monoid.
There are also monoids that take a parameter of kind * that would overlap with this instance. So we can't (and shouldn't) have the global Monoid instance like you give there first. As for the particular case of IO a, lifting may be a reasonable option there. A case could be made for adding an `instance Monoid a => Monoid (IO a)`, but for such a ubiquitously used type, expect that this wouldn't be an easy sell. You'd possibly have to deal with everyone and their brother coming out of the woodwork offering up every other Monoid they happened to use on IO. Why? IO provides a notion of failing action you could use for zero and you can build an (<|>) like construction on it as well, so the 'multiplicative' structure isn't the _only_ option for your monoid. Even within the multiplicative structure using the monoid isn't necessarily ideal as you might leak more memory with an IO a monoid that lifts () than you would with working specifically on IO (). You can argue the case that the choice you made is a sensible default instance by instance, but when there isn't a real canonical choice we do tend to err on the side of leaving things open as orphans are at least possible, but once the choice is made it is very very hard to unmake. I say this mostly so you know the kinds of objections proposals like this usually see, not to flat out reject the idea of the particular case of this instance for IO. I will say the global 'instance (Applicative f, Monoid m) => Monoid (f m)' won't fly for overlap reasons though. -Edward On Mon, Jul 14, 2014 at 6:55 PM, Brandon Simmons < brandon.m.simm...@gmail.com> wrote: > It seems to me that this should be true for all `f a` like: > > instance (Monoid a, Applicative f)=> Monoid (f a) where > mappend = liftA2 mappend > mempty = pure mempty > > But I can't seem to find the particular `instance (Monoid a)=> Monoid > (IO a)` anywhere. Would that instance be incorrect, or does it live > somewhere else? > > FWIW I noticed this when I started thinking about an instance I wanted > for 'contravariant': > > instance (Monoid a, Applicative f)=> Monoid (Op (f a) b) where > mempty = Op $ const $ pure mempty > mappend (Op f) (Op g) = Op (\b-> liftA2 mappend (f b) (g b)) > > at which point I realized (I think) all `f a` are monoidal, and so we > ought to be able to get the instance above with just a deriving > Monoid. > > Brandon > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgowfirstname.lastname@example.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >
_______________________________________________ Glasgow-haskell-users mailing list Glasgowemail@example.com http://www.haskell.org/mailman/listinfo/glasgow-haskell-users