Proposal: Add missing Monoid for ZipList

http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm... There's a Monoid that matches what the Applicative for ZipList does that seems to be missing. instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend It's been brought up before: https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well. Are there any good reasons not to have it? I'd like to limit discussion to two weeks.

-1. This breaks the rule that "ZipList is [] with a different Applicative
instance". The monoid instance for lists would work just fine for these.
On Jul 25, 2015 4:50 PM, "Christopher Allen"
http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
I'd like to limit discussion to two weeks.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Sat, 25 Jul 2015, Christopher Allen wrote:
http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
The Monoid instance for lists is not related to Applicative list instance - so why should the instances for ZipList? We could as well use the Monoid list implementation for ZipLists. If there is no actual application for the instance I would leave it unimplemented.

We could as well use the Monoid list implementation for ZipLists.
We could, but that would be redundant and wouldn't fit what ZipList is for as well. On Sat, Jul 25, 2015 at 3:57 PM, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Sat, 25 Jul 2015, Christopher Allen wrote:
http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
The Monoid instance for lists is not related to Applicative list instance - so why should the instances for ZipList? We could as well use the Monoid list implementation for ZipLists. If there is no actual application for the instance I would leave it unimplemented.
-- Chris Allen Currently working on http://haskellbook.com

We could add a newtype for this in Data.Monoid.
newtype Appl f a = Appl (f a)
instance (Applicative f, Monoid a) => Monoid (Appl f a) where
mempty = Appl $ pure mempty
mplus (Appl x) (Appl y) = Appl $ liftA2 mplus x y
On Jul 25, 2015 4:50 PM, "Christopher Allen"
http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
I'd like to limit discussion to two weeks.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On 07/25/2015 05:13 PM, David Feuer wrote:
We could add a newtype for this in Data.Monoid.
newtype Appl f a = Appl (f a) instance (Applicative f, Monoid a) => Monoid (Appl f a) where mempty = Appl $ pure mempty mplus (Appl x) (Appl y) = Appl $ liftA2 mplus x y
I like this idea, it would go well with the recently-added Alt newtype. You should make it a separate proposal, though. I'm +0 on the parent proposal.

This is a neat idea, and potentially useful. +1. If this gets through, the instance should include documentation describing how it works (probably mentioning zipWith) and contrasting it with the Monoid [a] instance. On 25/07/15 23:50, Christopher Allen wrote:
http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
I'd like to limit discussion to two weeks.

There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where
mempty = ZipList []
mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where
go (x:xs) (y:ys) = x <> y : go xs ys
go xs [] = xs
go [] ys = ys
But +1 to the original one.
2015-07-26 5:50 GMT+09:00 Christopher Allen
http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
I'd like to limit discussion to two weeks.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Sorry, it should be `mappend (ZipList xs0) (ZipList ys0) = ZipList (go xs0
ys0) where`
2015-07-26 12:23 GMT+09:00 Fumiaki Kinoshita
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
But +1 to the original one.
2015-07-26 5:50 GMT+09:00 Christopher Allen
: http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
I'd like to limit discussion to two weeks.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Can someone please explain *why* they want this instance?
On Jul 25, 2015 11:23 PM, "Fumiaki Kinoshita"
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
But +1 to the original one.
2015-07-26 5:50 GMT+09:00 Christopher Allen
: http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.htm...
There's a Monoid that matches what the Applicative for ZipList does that seems to be missing.
instance Monoid a => Monoid (ZipList a) where mempty = pure mempty mappend = liftA2 mappend
It's been brought up before:
https://mail.haskell.org/pipermail/haskell-cafe/2009-October/067861.html
Not only is it useful when it's the Monoid you want, but it serves an educational purpose for highlighting the relationship between Monoid and Applicative as well.
Are there any good reasons not to have it?
I'd like to limit discussion to two weeks.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On 26/07/2015 at 12:23:13 +0900, Fumiaki Kinoshita wrote:
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
This breaks the identity law.

On 26 Jul 2015, at 06:43, M Farkas-Dyck
wrote: On 26/07/2015 at 12:23:13 +0900, Fumiaki Kinoshita wrote:
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
This breaks the identity law.
instance Monoid a a => Monoid (ZipList a) where mempty = ZipList (repeat mempty) mappend (ZipList xs) (ZipList ys) = ZipList (zipWith (<>) xs ys) No preference on actual proposal or the instance. I have no strong opinion whether Alternative and Monoid1 should be the same. Cheers, Oleg Grenrus

On Sun, 26 Jul 2015, Oleg Grenrus wrote:
On 26 Jul 2015, at 06:43, M Farkas-Dyck
wrote: On 26/07/2015 at 12:23:13 +0900, Fumiaki Kinoshita wrote:
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
This breaks the identity law.
I don't see, how it breaks the identity law. :-(
instance Monoid a a => Monoid (ZipList a) where mempty = ZipList (repeat mempty) mappend (ZipList xs) (ZipList ys) = ZipList (zipWith (<>) xs ys)
This was the original proposal, isn't it? Since there does not seem to be a real application for the instance there is no way to choose a particular one. But then it is better to omit the instance, at all. Not having an instance can be a good thing in terms of (type) safety.

On 26/07/2015 at 08:30:33 +0200, Henning Thielemann wrote:
On Sun, 26 Jul 2015, Oleg Grenrus wrote:
On 26 Jul 2015, at 06:43, M Farkas-Dyck
wrote: On 26/07/2015 at 12:23:13 +0900, Fumiaki Kinoshita wrote:
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
This breaks the identity law.
I don't see, how it breaks the identity law. :-(
Derp. I misread the code, sorry.

Sorry, that seems to be exactly the instances which is originally proposed.
On 26 Jul 2015, at 09:20, Oleg Grenrus
wrote: On 26 Jul 2015, at 06:43, M Farkas-Dyck
wrote: On 26/07/2015 at 12:23:13 +0900, Fumiaki Kinoshita wrote:
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
This breaks the identity law.
instance Monoid a a => Monoid (ZipList a) where mempty = ZipList (repeat mempty) mappend (ZipList xs) (ZipList ys) = ZipList (zipWith (<>) xs ys)
No preference on actual proposal or the instance. I have no strong opinion whether Alternative and Monoid1 should be the same.
Cheers, Oleg Grenrus _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Fumiaka Kinoshita's instance actually seems both sound and "slightly more
defined".
It even relates more obviously to the proposed Alternative, which can be
seen as exploiting the fact that the First semigroup can be applied on any
data type and then using this instance.
m <|> n = fmap getFirst (fmap First m <> fmap First n)
-Edward
On Sat, Jul 25, 2015 at 11:43 PM, M Farkas-Dyck
On 26/07/2015 at 12:23:13 +0900, Fumiaki Kinoshita wrote:
There is another possible instance:
instance Semigroup a => Monoid (ZipList a) where mempty = ZipList [] mappend (ZipList xs0) (ZipList ys0) = ZipList (mappend xs0 ys0) where go (x:xs) (y:ys) = x <> y : go xs ys go xs [] = xs go [] ys = ys
This breaks the identity law. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (9)
-
Christopher Allen
-
David Feuer
-
Edward Kmett
-
Fumiaki Kinoshita
-
Henning Thielemann
-
M Farkas-Dyck
-
Mario Blažević
-
Oleg Grenrus
-
Roman Cheplyaka