<div dir="ltr"><span style="font-size:12.8px">I'm glad you agree that it will be worthwhile. Thank you for cutting out the cruft from my code.</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">I've added a request to <a href="http://hub.darcs.net/ross/transformers/issue/38" target="_blank">http://hub.darcs.net/ross/<wbr>transformers/issue/38</a></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 22 March 2017 at 08:09, David Feuer <span dir="ltr"><<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Yes, this is valid, and we should probably do it.<br>
<br>
mempty = pure mempty<br>
mappend = liftA2 mappend<br>
<br>
will make a valid Monoid for any Applicative instance, and<br>
<br>
x <> y = (<>) <$> x <.> y<br>
<br>
will make a valid Semigroup for any Apply instance. Proving this seems<br>
a bit gross. It's probably best to go via a well-known alternative<br>
formulation of Applicative:<br>
<br>
class Functor f => Apply' f where<br>
pair :: f a -> f b -> f (a, b)<br>
instance Apply' f => Applicative' f where<br>
pure' :: a -> f a<br>
<br>
This formulation lets you reassociate by switching between (a, (b,c))<br>
and ((a,b),c) rather than shifting fmaps around.<br>
<div><div class="h5"><br>
On Tue, Mar 21, 2017 at 3:53 AM, Louis Pan <<a href="mailto:louis@pan.me">louis@pan.me</a>> wrote:<br>
> Hi all,<br>
><br>
> In my Glazier GUI library, I had to use newtype wrappers to create Semigroup<br>
> and Monoid instances for ReaderT.<br>
><br>
> Is there a reason why ReaderT doesn't have an instance of Semigroup and<br>
> Monoid?<br>
><br>
> The reader ((->) a) is a Monoid and a Semigroup.<br>
> <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC.Base.html#line-268" rel="noreferrer" target="_blank">https://hackage.haskell.org/<wbr>package/base-4.9.1.0/docs/src/<wbr>GHC.Base.html#line-268</a><br>
> <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/src/Data.Semigroup.html#line-150" rel="noreferrer" target="_blank">https://hackage.haskell.org/<wbr>package/base-4.9.1.0/docs/src/<wbr>Data.Semigroup.html#line-150</a><br>
><br>
> Could the following be added to the transformers package? Or is it not<br>
> lawful?<br>
><br>
> instance (Applicative m, Semigroup a) => Semigroup (ReaderT r m a) where<br>
> f <> g = (<>) <$> f <*> g<br>
> {-# INLINABLE (<>) #-}<br>
><br>
> instance (Applicative m, Monoid a) => Monoid (ReaderT r m a) where<br>
> mempty = pure mempty<br>
> {-# INLINABLE mempty #-}<br>
><br>
> f `mappend` g = mappend <$> f <*> g<br>
> {-# INLINABLE mappend #-}<br>
><br>
> Does it make sense to extend the monoid instance to all the other<br>
> transformers? Eg.<br>
><br>
> instance (Monad m, Semigroup a) => Semigroup (StateT s m a) where<br>
> f <> g = (<>) <$> f <*> g<br>
> {-# INLINABLE (<>) #-}<br>
><br>
> instance (Monad m, Monoid a) => Monoid (StateT s m a) where<br>
> mempty = pure mempty<br>
> {-# INLINABLE mempty #-}<br>
><br>
> f `mappend` g = mappend <$> f <*> g<br>
> {-# INLINABLE mappend #-}<br>
><br>
> instance (Monad m, Monoid w, Semigroup a) => Semigroup (WriterT w m a) where<br>
> f <> g = (<>) <$> f <*> g<br>
> {-# INLINABLE (<>) #-}<br>
><br>
> instance (Monad m, Monoid w, Monoid a) => Monoid (WriterT w m a) where<br>
> mempty = pure mempty<br>
> {-# INLINABLE mempty #-}<br>
><br>
> f `mappend` g = mappend <$> f <*> g<br>
> {-# INLINABLE mappend #-}<br>
><br>
> and also for MaybeT, IdentityT, ExceptT, etc<br>
><br>
><br>
> Regards,<br>
><br>
> Louis<br>
><br>
</div></div>> ______________________________<wbr>_________________<br>
> Haskell-Cafe mailing list<br>
> To (un)subscribe, modify options or view archives go to:<br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
> Only members subscribed via the mailman list are allowed to post.<br>
</blockquote></div><br></div>