concrete functor and monad transformers

#38Please add Semigroup and Monoid instances

Would it make sense to add Semigroup and Monoid instances to the transformer newtype wrappers?

See https://mail.haskell.org/pipermail/haskell-cafe/2017-March/126588.html

Eg.

instance (Applicative m, Monoid a) => Monoid (ReaderT r m a)
    mempty = pure mempty
    mappend = liftA2 mappend

instance (Applicative m, Semigroup a) => Semigroup (ReaderT r m a)
    (<>) = liftA2 (<>)

and similar for the other transformer newtype wrappers.

David Feuer notes that the Semigroup instance actually only need an "Apply" instance, but I'm not sure how you'll be able to add Apply to the transformer package.

Olaf Klinke notes that in general:

instance (Semigroup a, Applicative f) => Semigroup (f a) where
  (<>) = liftA2 (<>)

but unfortunately that will lead to overlapping instances.

Therefore, I feel adding the instances to the transformer newtypes is a good middle ground.

    • status set to closed

    David Menendez notes that "there are at least three reasonable instances of Semigroup and Monoid for ReaderT."

    instance (Applicative m, Monoid a) => Monoid (ReaderT r m a) where
        mempty = pure mempty
        mappend a b = mappend <$> a <*> b
    
    instance (Alternative m) => Monoid (ReaderT r m a) where
        mempty = empty
        mappend = (<|>)
    
    instance (Monoid (m a)) => Monoid (ReaderT r m a) where
        mempty = ReaderT $ mempty
        mappend a b = ReaderT $ mappend a b

    "In the absence of a principled reason to prefer one over the others and a general consensus, I think it’s better not to choose."

    Therefore, I'm closing this request.