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

Daniel Cartwright chessai1996 at gmail.com
Fri Nov 30 22:25:12 UTC 2018


Ah, yeah, I see that now, in the "natural" comment. In that case I'm not
sure if I prefer the version with FlexibleContexts or QuantifiedConstraints.

On Fri, Nov 30, 2018, 5:18 PM David Feuer <david.feuer at gmail.com wrote:

> 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/8a63da97/attachment.html>


More information about the Libraries mailing list