On Mon, Jul 14, 2014 at 10:55 PM, Edward Kmett <ekm...@gmail.com> wrote: > 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.
Right, sorry. I just meant that as a bit of context. My proposal is adding `instance Monoid a => Monoid (IO a)`. > > 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. Can you give an example of what you mean here? Would that be something involving exceptions? > > 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. Right like Sum/Product for Num types. But here there's good reason, I think, to choose one instance over others, because we already have the monoid structure of Applicative and Monad. You can still have a wrapper newtype with different instances for the alternatives, as was done with Applicative for [] and ZipList. But I might be misunderstanding, since I'm not really sure what the alternative instances you mention would look like. Thanks, Brandon > > 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 >> Glasgow-haskell-users@haskell.org >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > > _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users