[Haskell-cafe] Semigroup and Monoid instances for ReaderT

Louis Pan louis at pan.me
Tue Mar 21 07:53:59 UTC 2017


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20170321/83ca627c/attachment.html>


More information about the Haskell-Cafe mailing list