John Wiegley | 11 Jun 20:46 2013

Proposal: Add Data.Semigroup to base, as a superclass of Monoid

1. I propose that we add the following package to base:

     http://hackage.haskell.org/packages/archive/semigroups/0.9.2/doc/html/Data-Semigroup.html

   This is somewhat in the spirit of the AMP proposal: further improving the
   correctness of our algebraic abstractions.

2. That we make Semigroup a superclass of Monoid, so that (minimally):

     class Semigroup a where
         (<>) :: a -> a -> a

     class Semigroup a => Monoid a where
         mempty :: a
         mconcat :: [a] -> a
         mconcat = foldr (<>) mempty

     mappend :: Semigroup a => a -> a -> a
     mappend = (<>)

3. (Optional, recommended) There are other useful functions that can be added
   to Semigroup, such as sconcat and times1p, but I will let Edward speak to
   whether those should be proposed at this time.

4. (Optional, recommended) That we fix the Monoid instance for Maybe to be:

    instance Semigroup a => Semigroup (Maybe a) where
         Just x <> Just y = Just (x <> y)
         _ <> _ = Nothing

(Continue reading)

John Wiegley | 11 Jun 20:51 2013

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

>>>>> John Wiegley <johnw <at> fpcomplete.com> writes:

> 4. (Optional, recommended) That we fix the Monoid instance for Maybe to be:

>     instance Semigroup a => Semigroup (Maybe a) where
>          Just x <> Just y = Just (x <> y)
>          _ <> _ = Nothing

Slight correction (thanks to Brent Yorgey for catching this):

    instance Semigroup a => Semigroup (Maybe a) where
         Just x <> Just y = Just (x <> y)
         Nothing <> x = x
         x <> Nothing = x

--

-- 
John Wiegley
FP Complete                         Haskell tools, training and consulting
http://fpcomplete.com               johnw on #haskell/irc.freenode.net
Mario Blažević | 11 Jun 23:05 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

On 06/11/13 14:46, John Wiegley wrote:
> 1. I propose that we add the following package to base:
>
>       http://hackage.haskell.org/packages/archive/semigroups/0.9.2/doc/html/Data-Semigroup.html
>
>     This is somewhat in the spirit of the AMP proposal: further improving the
>     correctness of our algebraic abstractions.

     I was wondering how much longer until this proposal came up. +1 
from me in general, but I have some quibbles with details.

> 2. That we make Semigroup a superclass of Monoid, so that (minimally):
>
>       class Semigroup a where
>           (<>) :: a -> a -> a
>
>       class Semigroup a => Monoid a where
>           mempty :: a
>           mconcat :: [a] -> a
>           mconcat = foldr (<>) mempty
>
>       mappend :: Semigroup a => a -> a -> a
>       mappend = (<>)

     +1, though I'd prefer to leave mappend restricted to the Monoid 
class. In the long term, I'd rather have it killed off than kept as a 
synonym for (<>). Besides, it's m(onoid)append.

> 3. (Optional, recommended) There are other useful functions that can be added
>     to Semigroup, such as sconcat and times1p, but I will let Edward speak to
(Continue reading)

Edward Kmett | 11 Jun 23:50 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

I find myself somewhat on the fence about this proposal.

Ultimately, I'd like to see semigroups in base.

That said doing so with the current changes in flight is somewhat awkward, and introducing it carries a lot of distributed work.

We have two outstanding proposals that have received overwhelming support: namely the Applicative => Monad (AMP) proposal and the generalization of the types in the Prelude for mapM, etc. to use Foldable and Traversable (FT). Between these two proposals, we wind up with the need to bring in Foldable, Traversable, Applicative and Monoid into the Prelude. Applicative as a superclass of Monad and for traverse and Monoid because Foldable brings in foldMap.

Consequently fixing the situation to make Semigroup a superclass of Monoid isn't something that can be done purely by adding a module to base, but it would infect Prelude. 

This makes it have to clear a much higher bar!

A real proposal that involved adding Semigroup as a superclass of Monoid could possibly be concocted like David's AMP patch, whereupon Monoid would be given a default mappend = (<>)

That could enable users to just have to write an extra instance line like they would for the AMP, but it has some immediate headaches. 

In particular (<>) has been in use in pretty printing libraries since time immemorial. Suddenly exporting a version from the Prelude is likely to be a fairly breaking change to those libraries as the associativity of the (<>) provided by Data.Monoid (and the one provided by Data.Semigroup) both disagree with the (<>) in Text.PrettyPrint.HughesPJ, which is in the platform already. This could lead to some rather annoying breakages -- worse, silent breakages. I seem to recall that there was some concern that this would change the output of some pretty printing in GHC when the associativity issue was last raised on this list over the introduction of (<>).

I think to have a serious proposal that could actually be accepted, a lot of work would have to be put into a patch and then it would need to be explored how much the associativity issue bites users in practice along with gauging the amount of effort that would be involved in retrofitting semigroup instances into virtually everyone's libraries.

My knee jerk reaction is to try to put this off until the dust has settled from the AMP and FT changes and push back with a request for the necessary analysis.

-Edward


On Tue, Jun 11, 2013 at 5:05 PM, Mario Blažević <blamario <at> acanac.net> wrote:
On 06/11/13 14:46, John Wiegley wrote:
1. I propose that we add the following package to base:

      http://hackage.haskell.org/packages/archive/semigroups/0.9.2/doc/html/Data-Semigroup.html

    This is somewhat in the spirit of the AMP proposal: further improving the
    correctness of our algebraic abstractions.


    I was wondering how much longer until this proposal came up. +1 from me in general, but I have some quibbles with details.



2. That we make Semigroup a superclass of Monoid, so that (minimally):

      class Semigroup a where
          (<>) :: a -> a -> a

      class Semigroup a => Monoid a where
          mempty :: a
          mconcat :: [a] -> a
          mconcat = foldr (<>) mempty

      mappend :: Semigroup a => a -> a -> a
      mappend = (<>)


    +1, though I'd prefer to leave mappend restricted to the Monoid class. In the long term, I'd rather have it killed off than kept as a synonym for (<>). Besides, it's m(onoid)append.




3. (Optional, recommended) There are other useful functions that can be added
    to Semigroup, such as sconcat and times1p, but I will let Edward speak to
    whether those should be proposed at this time.


    They should be added in now or never, there's no reason to break compatibility twice. I don't think times1p can be accepted in its current form as it depends on a different library. Edward, can you make a concrete proposal for these?



4. (Optional, recommended) That we fix the Monoid instance for Maybe to be:

     instance Semigroup a => Monoid (Maybe a) where
          mempty = Nothing

     instance Semigroup a => Semigroup (Maybe a) where
          Just x <> Just y = Just (x <> y)
          Nothing <> x = x
          x <> Nothing = x


+1




_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Gabriel Gonzalez | 12 Jun 00:04 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

-1

I think types that lack an empty element are a misfeature.  They usually end up contaminating everything they touch, which is why semigroups forms an entire parallel ecosystem of its own.  This is a very slippery slope that won't end with the addition of `Data.Semigroup` and once it is in it will be impossible to take it out.
_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Herbert Valerio Riedel | 12 Jun 12:28 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

On 2013-06-12 at 00:04:04 +0200, Gabriel Gonzalez wrote:
> I think types that lack an empty element are a misfeature.  

...so having a data-type for representing non-empty lists (on which
operation such as head/last/minimum/maximum et. al can be proper
statically guaranteed total functions as opposed to resorting to
'Maybe'-wrapped results which need to be checked dynamically at runtime)
is a misfeature?

> They usually end up contaminating everything they touch, which is why
> semigroups forms an entire parallel ecosystem of its own.

Can you provide a concrete example showing the kind of problematic
"contamination" that is caused by semigroup-forming types?

cheers,
  hvr
Johan Tibell | 12 Jun 00:40 2013
Picon

Fwd: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

-1 This has the same problem as making Functor a superclass of Monad, all current instances will break.

This is somewhat in the spirit of the AMP proposal: further improving the
> correctness of our algebraic abstractions.

I don't think building a tower of all possible algebraic abstractions is a useful goal. We should add those that are actually useful (which functors, applicative functions, monads, and monoids have proved to be). I don't want to see us break all current code every time someone decides that we should add another layer (pointed, say) between e.g. functor and monad.



On Tue, Jun 11, 2013 at 11:46 AM, John Wiegley <johnw <at> fpcomplete.com> wrote:
1. I propose that we add the following package to base:

     http://hackage.haskell.org/packages/archive/semigroups/0.9.2/doc/html/Data-Semigroup.html

   This is somewhat in the spirit of the AMP proposal: further improving the
   correctness of our algebraic abstractions.

2. That we make Semigroup a superclass of Monoid, so that (minimally):

     class Semigroup a where
         (<>) :: a -> a -> a

     class Semigroup a => Monoid a where
         mempty :: a
         mconcat :: [a] -> a
         mconcat = foldr (<>) mempty

     mappend :: Semigroup a => a -> a -> a
     mappend = (<>)

3. (Optional, recommended) There are other useful functions that can be added
   to Semigroup, such as sconcat and times1p, but I will let Edward speak to
   whether those should be proposed at this time.

4. (Optional, recommended) That we fix the Monoid instance for Maybe to be:

    instance Semigroup a => Semigroup (Maybe a) where
         Just x <> Just y = Just (x <> y)
         _ <> _ = Nothing

    instance Semigroup a => Monoid (Maybe a) where
         mempty = Nothing


For some clarification on what semigroups are and why we'd want to change
Monoid, I excerpt here a selection from Brent Yorgey's "Monoids and
Variations" paper:

                                  Semigroups

  A semigroup is like a monoid without the requirement of an identity element:
  it consists simply of a set with an associative binary operation....

  Of course, any monoid is automatically a semigroup (by forgetting about its
  identity element).  In the other direction, to turn a semigroup into a
  monoid, simply add a new distinguished element to serve as the identity, and
  extend the definition of the binary operation appropriately.  This creates
  an identity element by definition, and it is not hard to see that it
  preserves associativity....

  Adding a new distinguished element to a type is typically accomplished by
  wrapping it in Maybe.  One might therefore expect to turn an instance of
  Semigroup into an instance of Monoid by wrapping it in Maybe.  Sadly,
  Data.Monoid does not define semigroups, and has a Monoid instance for Maybe
  which requires a Monoid constraint on its argument type...

  This is somewhat odd: in essence, it ignores the identity element of [the
  type] and replaces it with a different one.

--
John Wiegley
FP Complete                         Haskell tools, training and consulting
http://fpcomplete.com               johnw on #haskell/irc.freenode.net

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Nikita Volkov | 12 Jun 11:03 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid


On Jun 12, 2013, at 2:40 AM, Johan Tibell <johan.tibell <at> gmail.com> wrote:

I don't want to see us break all current code every time someone decides that we should add another layer (pointed, say) between e.g. functor and monad.

This can also be considered a good argument to make as many of the breaking changes as possible at once. This is why I believe we should initiate polls on all imaginable initiatives, including the Pointed. My votes for Semigroup and Pointed are neutral, i.e. 0 and 0.

Concerning the discussion on Monoid's <>. Since we've stepped on a path of Prelude generalization, what about reimplementing the ++ in terms of Monoid? It's proven to be quite useful in the Snoyman's (of Yesod) classy-prelude experiment. Just think about it: we don't lose anything, and we get the expected String-like API for working with Text, ByteString and etc, and we also free up the <> operator.
_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Andreas Abel | 12 Jun 22:13 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

On 12.06.13 11:03 AM, Nikita Volkov wrote:
>
> Concerning the discussion on Monoid's <>. Since we've stepped on a path
> of Prelude generalization, what about reimplementing the ++ in terms of
> Monoid? It's proven to be quite useful in the Snoyman's (of Yesod)
> classy-prelude
>
<http://hackage.haskell.org/packages/archive/classy-prelude/0.5.8/doc/html/ClassyPrelude.html#v:-43--43-> experiment.
> Just think about it: we don't lose anything, and we get the expected
> String-like API for working with Text, ByteString and etc, and we also
> free up the <> operator.

Makes sense.

+1 for ++ instead of <>.   Both are right-associative, so there are no 
problems with that.

--

-- 
Andreas Abel  <><      Du bist der geliebte Mensch.

Theoretical Computer Science, University of Munich
Oettingenstr. 67, D-80538 Munich, GERMANY

andreas.abel <at> ifi.lmu.de
http://www2.tcs.ifi.lmu.de/~abel/
Stephen Tetley | 13 Jun 19:05 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

-1

I'm against adding Semigroup to Base as it only has one useful operation in the class and no useful generic functions (without adding more overhead to Base - non-empty lists, naturals...).


_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Petr Pudlák | 13 Jun 20:20 2013
Picon

Re: Proposal: Add Data.Semigroup to base, as a superclass of Monoid

Dne 06/13/2013 07:05 PM, Stephen Tetley napsal(a):
-1 I'm against adding Semigroup to Base as it only has one useful operation in the class and no useful generic functions (without adding more overhead to Base - non-empty lists, naturals...).
The most useful function from Semigroups for me is `times1p` (or its monoidal variant `timesN`). What about adding a function similar to `timesN` (perhaps with another name) to Prelude (and implement `(^)` with it)?

  Petr



_______________________________________________ Libraries mailing list Libraries <at> haskell.org http://www.haskell.org/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

Gmane