Proposal: Add Semigroup/Monoid instance to Data.Functor.Compose

David Feuer david.feuer at gmail.com
Fri Nov 30 22:18:38 UTC 2018


I'm suggesting that the lifting instance is the *wrong one*. Lifting is
Ap's job. Compose is just for composing things.

On Fri, Nov 30, 2018, 5:14 PM Daniel Cartwright <chessai1996 at gmail.com
wrote:

> Yeah, the instance being defined with Ap is certainly a good way to go. We
> can use DerivingVia and Data.Monoid.Ap.
>
>
> On Fri, Nov 30, 2018, 4:55 PM David Feuer <david.feuer at gmail.com wrote:
>
>> The alternate one can be written much more simply with
>> FlexibleContexts instead of QuantifiedConstraints:
>>
>> instance Semigroup (f (g a)) => Semigroup (Compose f g a) where
>>   Compose x <> Compose y = Compose (x <> y)
>> instance Monoid (f (g a)) => Monoid (Compose f g a) where
>>   mempty = Compose mempty
>>
>> That strikes me as the most natural way to do it. The lifting
>> instances are more naturally done using this oft-proposed type:
>>
>> newtype Ap f a = Ap (f a)
>> instance (Applicative f, Semigroup a) => Semigroup (Ap f a) where
>>   Ap x <> Ap y = Ap (liftA2 (<>) x y)
>> instance (Applicative f, Monoid a) => Monoid (Ap f a) where
>>   mempty = pure mempty
>>
>> Now Ap (Compose f g) a will do the lifting you want.
>>
>> On Fri, Nov 30, 2018 at 4:13 PM Daniel Cartwright <chessai1996 at gmail.com>
>> wrote:
>> >
>> > Data.Functor.Compose:
>> >
>> > newtype Compose f g a = Compose { getCompose :: f (g a) }
>> >
>> > there's clear-cut, more traditional instances if `f` and `g` are
>> Applicative:
>> >
>> > instance (Applicative f, Applicative g, Semigroup a) => Semigroup
>> (Compose f g a) where
>> >   (<>) = liftA2 (<>)
>> >
>> > instance (Applicative f, Applicative g, Monoid a) => Monoid (Compose f
>> g a) where
>> >   mempty = pure mempty
>> >
>> > There's an alternative with `QuantifiedConstraints`, but it's arguable
>> that this is desirable:
>> >
>> > instance (forall x. Semigroup x => Semigroup (f x), forall x. Semigroup
>> x => Semigroup (g x), Semigroup a) => Semigroup (Compose f g a) where
>> >   Compose x <> Compose y = Compose (x <> y)
>> >
>> > Both to seem to fit the commonplace spirit of lifting monoids up
>> through applicative contexts.
>> > _______________________________________________
>> > Libraries mailing list
>> > Libraries at haskell.org
>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20181130/106ea9c2/attachment.html>


More information about the Libraries mailing list