
Hi all, In my Glazier GUI library, I had to use newtype wrappers to create Semigroup and Monoid instances for ReaderT. Is there a reason why ReaderT doesn't have an instance of Semigroup and Monoid? The reader ((->) a) is a Monoid and a Semigroup. https://hackage.haskell.org/package/base-4.9.1.0/docs/src/ GHC.Base.html#line-268 https://hackage.haskell.org/package/base-4.9.1.0/docs/src/ Data.Semigroup.html#line-150 Could the following be added to the transformers package? Or is it not lawful? instance (Applicative m, Semigroup a) => Semigroup (ReaderT r m a) where f <> g = (<>) <$> f <*> g {-# INLINABLE (<>) #-} instance (Applicative m, Monoid a) => Monoid (ReaderT r m a) where mempty = pure mempty {-# INLINABLE mempty #-} f `mappend` g = mappend <$> f <*> g {-# INLINABLE mappend #-} Does it make sense to extend the monoid instance to all the other transformers? Eg. instance (Monad m, Semigroup a) => Semigroup (StateT s m a) where f <> g = (<>) <$> f <*> g {-# INLINABLE (<>) #-} instance (Monad m, Monoid a) => Monoid (StateT s m a) where mempty = pure mempty {-# INLINABLE mempty #-} f `mappend` g = mappend <$> f <*> g {-# INLINABLE mappend #-} instance (Monad m, Monoid w, Semigroup a) => Semigroup (WriterT w m a) where f <> g = (<>) <$> f <*> g {-# INLINABLE (<>) #-} instance (Monad m, Monoid w, Monoid a) => Monoid (WriterT w m a) where mempty = pure mempty {-# INLINABLE mempty #-} f `mappend` g = mappend <$> f <*> g {-# INLINABLE mappend #-} and also for MaybeT, IdentityT, ExceptT, etc Regards, Louis