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.
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