Discussion:
Monoid for ZipList
박신환
2018-05-03 09:22:16 UTC
Permalink
As instance Alternative ZipList is defined since 4.11.0.0:
instanceAlternativeZipListwhereempty=ZipList[]ZipList<|>ZipList=ZipList(xs++drop(lengthxs)ys)

It seems perfectly fine to make Monoid for ZipList as followings:

instance Semigroup a => Semigroup (ZipList a) where
ZipList [] <> ZipList ys = ZipList ys
ZipList xs <> ZipList [] = ZipList xs
ZipList (x:xs) <> ZipList (y:ys) = ZipList (x <> y : ZipList xs <> ZipList ys)

instance Semigroup a => Monoid (ZipList a) where
mempty = ZipList []

Note that this semantic is similar to that of Maybe​.
Andrew Martin
2018-05-03 12:05:24 UTC
Permalink
There is another possible instance. We can instead write:

instance Semigroup a => Semigroup (ZipList a) where
(<>) = liftA2 (<>)
instance Monoid a => Monoid (ZipList a) where
mempty = pure mempty

This behaves differently, and it is also law-abiding.
*instance Alternative <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/GHC.Base.html#Alternative> ZipList <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#ZipList> where
empty <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/GHC.Base.html#empty> = ZipList <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#ZipList> []
ZipList <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#ZipList> xs <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#local-6989586621679319881> <|> <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/GHC.Base.html#%3C%7C%3E> ZipList <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#ZipList> ys <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#local-6989586621679319882> = ZipList <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#ZipList> (xs <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#local-6989586621679319881> ++ <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/GHC.Base.html#%2B%2B> drop <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/GHC.List.html#drop> (length <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Data.Foldable.html#length> xs <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#local-6989586621679319881>) ys <http://hackage.haskell.org/package/base-4.11.1.0/docs/src/Control.Applicative.html#local-6989586621679319882>*
*)*
*instance Semigroup a => Semigroup (ZipList a) where ZipList [] <> ZipList ys = ZipList ys ZipList xs <> ZipList [] = ZipList xs ZipList (x:xs) <> ZipList (y:ys) = ZipList (x <> y : ZipList xs <> ZipList ys)instance Semigroup a => Monoid (ZipList a) where mempty = ZipList []*
Note that this semantic is similar to that of *Maybe*​.
_______________________________________________
Libraries mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
--
-Andrew Thaddeus Martin
박신환
2018-05-03 23:40:44 UTC
Permalink
I aim to make the semantic consistent compared to that of other type classes (here Maybe).

Also note that your instance is identical to upcoming Ap, as Ap (ZipList a). I also aim to make Monoids as diverse as possible.


-----Original Message-----
From: "Andrew Martin"<***@gmail.com>
To: "박신환"<***@naver.com>;
Cc: "Haskell Libraries"<***@haskell.org>;
Sent: 2018-05-03 (목) 21:05:24
Subject: Re: Monoid for ZipList

There is another possible instance. We can instead write:

instance Semigroup a => Semigroup (ZipList a) where
(<>) = liftA2 (<>)
instance Monoid a => Monoid (ZipList a) where
mempty = pure mempty

This behaves differently, and it is also law-abiding.
Edward Kmett
2018-05-04 22:04:05 UTC
Permalink
It is worth noting that Maybe a and [a] are rather special cases. The former is the monoid you get from adjoining a unit to a semigroup. The latter is the free monoid. Most other monoids for things wrapped in an applicative are either based on the Alternative instance which inherently provides a monoidal structure or based on lifting a monoid pointwise into the data type.

Here we have at least 3-4 possible, quite reasonable, monoids at play, and no real reason to choose any one of them over the others. In that situation, our general practice thus far has been to resist choosing if a choice hasn't already been made, simply because there is no real manner other than memorization / code inspection for a user to know which instance we happened to pick.

I'm -1 on adding the instance proposed here.

Sent from my iPhone
Post by 박신환
I aim to make the semantic consistent compared to that of other type classes (here Maybe).
Also note that your instance is identical to upcoming Ap, as Ap (ZipList a). I also aim to make Monoids as diverse as possible.
-----Original Message-----
Sent: 2018-05-03 (목) 21:05:24
Subject: Re: Monoid for ZipList
instance Semigroup a => Semigroup (ZipList a) where
(<>) = liftA2 (<>)
instance Monoid a => Monoid (ZipList a) where
mempty = pure mempty
This behaves differently, and it is also law-abiding.
_______________________________________________
Libraries mailing list
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
박신환
2018-05-05 07:38:33 UTC
Permalink
I'm not refering that Maybe makes Monoid by adding the identity element. I'm refering that the Monoid (Maybe (First a)) have the same semantic as Alternative Maybe.

So I'm suggesting that the same semantic should go to Monoid (ZipList (First a)) for Alternative ZipList.


-----Original Message-----
From: "Edward Kmett"<***@gmail.com>
To: "박신환"<***@naver.com>;
Cc: "Haskell Libraries"<***@haskell.org>;
Sent: 2018-05-05 (토) 07:04:05
Subject: Re: Monoid for ZipList

It is worth noting that Maybe a and [a] are rather special cases. The former is the monoid you get from adjoining a unit to a semigroup. The latter is the free monoid. Most other monoids for things wrapped in an applicative are either based on the Alternative instance which inherently provides a monoidal structure or based on lifting a monoid pointwise into the data type.

Here we have at least 3-4 possible, quite reasonable, monoids at play, and no real reason to choose any one of them over the others. In that situation, our general practice thus far has been to resist choosing if a choice hasn't already been made, simply because there is no real manner other than memorization / code inspection for a user to know which instance we happened to pick.

I'm -1 on adding the instance proposed here.

Sent from my iPhone

Loading...