Frerich Raabe | 18 Jul 21:26 2014

Proposal: add 'equating' function to Data.List

Hi,

A common use case for 'on' (from Data.Function) is to use it with 'compare', 
e.g. 'compare `on` snd'. In fact, this pattern is so common that there's a 
convenient 'comparing' function which provides a shortcut for this use case 
such that one can write

   sortBy (comparing snd)

instead of

   sortBy (compare `on` snd)

I think another common use case is to use 'on' together with (==) as in

   groupBy ((==) `on` snd)

In a similiar vein as with 'comparing', I think it would be nice if there 
was a function which encapsulates this use case, like

   equating :: Eq b => (a -> b) -> a -> a -> Bool
   equating = on (==)

such that one can write

   groupBy (equating snd)

In fact, groupBy is just one of many *By functions taking an a -> a -> Bool 
-- many of which are Data.List, e.g. groupBy, nubBy, deleteBy, intersectBy, 
unionBy. Hence, it seems plausible to define 'equating' in Data.List. This is 
(Continue reading)

Henning Thielemann | 18 Jul 21:31 2014
Picon

Re: Proposal: add 'equating' function to Data.List

Am 18.07.2014 21:26, schrieb Frerich Raabe:

> In a similiar vein as with 'comparing', I think it would be nice if
> there was a function which encapsulates this use case, like
>
>    equating :: Eq b => (a -> b) -> a -> a -> Bool
>    equating = on (==)
>
> such that one can write
>
>    groupBy (equating snd)

I think it belongs to Data.Eq.

I have already added it to my own Data.Eq module:

http://hackage.haskell.org/package/utility-ht-0.0.10/docs/Data-Eq-HT.html

this way I do not need to depend on a new GHC version in order to use it.
Andreas Abel | 18 Jul 23:11 2014
Picon
Picon

Re: Proposal: add 'equating' function to Data.List

I am not super excited about library functions like

   comparing = (compare `on`)
   equating  = ((==) `on`)

It is rather knowledge how to use 'on', a programming pattern.  The 
problem we have to solve is how we get a user searching for

   sortOn : Ord b => (a -> b) -> [a] -> [a]

to find an explanation of the simple solution

   sortOn f = sortBy (compare `on` f)

This problem of API explanation has been discussed on this list.  Maybe 
instead of adding such simple functions to the library, one could put 
out a hoogle- and hayoo-indexed package that contains all such functions 
that could be expected to be in the library but are not since they have 
trivial implementations.

Cheers,
Andreas

P.S.: In fact, `sortOn' would be more useful than `comparing' since it 
at least saves two words.

On 18.07.2014 21:31, Henning Thielemann wrote:
> Am 18.07.2014 21:26, schrieb Frerich Raabe:
>
>> In a similiar vein as with 'comparing', I think it would be nice if
(Continue reading)

Edward Kmett | 19 Jul 14:44 2014
Picon

Re: Proposal: add 'equating' function to Data.List

I'm ever so slightly +1 on this proposal.

Why? Because it gets reinvented every 4 months, and by just adding it we can stop having this discussion.

I hereby proposed there exists a "co-Fairbairn threshold", the point at which the traffic caused by
fighting against adding a commonly reinvented simple composition outweighs the pedagogical gain of
pushing people to understand the simpler parts.

That said, I'd prefer it live alongside comparing, and not get pushed redundantly around to other modules.

-Edward

> On Jul 18, 2014, at 5:11 PM, Andreas Abel <abela <at> chalmers.se> wrote:
> 
> I am not super excited about library functions like
> 
>  comparing = (compare `on`)
>  equating  = ((==) `on`)
> 
> It is rather knowledge how to use 'on', a programming pattern.  The problem we have to solve is how we get a
user searching for
> 
>  sortOn : Ord b => (a -> b) -> [a] -> [a]
> 
> to find an explanation of the simple solution
> 
>  sortOn f = sortBy (compare `on` f)
> 
> This problem of API explanation has been discussed on this list.  Maybe instead of adding such simple
functions to the library, one could put out a hoogle- and hayoo-indexed package that contains all such
(Continue reading)

Alexander Berntsen | 19 Jul 14:50 2014
Picon

Re: Proposal: add 'equating' function to Data.List


On 19/07/14 14:44, Edward Kmett wrote:
> I'm ever so slightly +1 on this proposal.
> 
> Why? Because it gets reinvented every 4 months, and by just adding
> it we can stop having this discussion.
> 
> I hereby proposed there exists a "co-Fairbairn threshold", the
> point at which the traffic caused by fighting against adding a
> commonly reinvented simple composition outweighs the pedagogical
> gain of pushing people to understand the simpler parts.
OK, you have me convinced. You should put these thresholds of yours on
the GHC Wiki or something. ;-)

> That said, I'd prefer it live alongside comparing, and not get
> pushed redundantly around to other modules.
I suggest:
equating :: Eq a => (b -> a) -> b -> b -> Bool
equating p x y = (p x) == (p y)

in Data.Eq, exposing it with

module Data.Eq (
   Eq(..),
 ) where

If this sounds good I can write a patch for it, test it & upload it to
phab to have it built & reviewed by austin and you. :-)
--

-- 
Alexander
(Continue reading)

Edward Kmett | 19 Jul 14:54 2014
Picon

Re: Proposal: add 'equating' function to Data.List

I didn't mean to preëmpt the whole discussion thread -- I'd rather let that play out, but I just wanted to
express where my personal opinion lies on this matter.

Data.Eq does sound like the right place for it, if we do go to put it in.

-Edward

> On Jul 19, 2014, at 8:50 AM, Alexander Berntsen <alexander <at> plaimi.net> wrote:
> 
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
> 
>> On 19/07/14 14:44, Edward Kmett wrote:
>> I'm ever so slightly +1 on this proposal.
>> 
>> Why? Because it gets reinvented every 4 months, and by just adding
>> it we can stop having this discussion.
>> 
>> I hereby proposed there exists a "co-Fairbairn threshold", the
>> point at which the traffic caused by fighting against adding a
>> commonly reinvented simple composition outweighs the pedagogical
>> gain of pushing people to understand the simpler parts.
> OK, you have me convinced. You should put these thresholds of yours on
> the GHC Wiki or something. ;-)
> 
>> That said, I'd prefer it live alongside comparing, and not get
>> pushed redundantly around to other modules.
> I suggest:
> equating :: Eq a => (b -> a) -> b -> b -> Bool
> equating p x y = (p x) == (p y)
(Continue reading)

Alexander Berntsen | 19 Jul 14:55 2014
Picon

Re: Proposal: add 'equating' function to Data.List


On 19/07/14 14:54, Edward Kmett wrote:
> I didn't mean to preëmpt the whole discussion thread -- I'd rather 
> let that play out, but I just wanted to express where my personal 
> opinion lies on this matter.
OK cool. I'm +1 now for what it's worth. :-]
--

-- 
Alexander
alexander <at> plaimi.net
https://secure.plaimi.net/~alexander
Alexander Berntsen | 19 Jul 14:50 2014
Picon

Re: Proposal: add 'equating' function to Data.List


On 19/07/14 14:44, Edward Kmett wrote:

OK, you have me convinced. You should put these thresholds of yours on
the GHC Wiki or something. ;-)

I suggest:
equating :: Eq a => (b -> a) -> b -> b -> Bool
equating p x y = (p x) == (p y)

in Data.Eq, exposing it with

module Data.Eq (
   Eq(..),
 ) where

If this sounds good I can write a patch for it, test it & upload it to
phab to have it built & reviewed by austin and you. :-)
--

-- 
Alexander
alexander <at> plaimi.net
https://secure.plaimi.net/~alexander
Frerich Raabe | 19 Jul 23:35 2014

Re: Proposal: add 'equating' function to Data.List

On 2014-07-18 23:11, Andreas Abel wrote:
> I am not super excited about library functions like
>
>   comparing = (compare `on`)
>   equating  = ((==) `on`)
>
> It is rather knowledge how to use 'on', a programming pattern.

I concur, but at the same time the argument given on this list by Robert 
Dockins' about seven years ago ( 
http://article.gmane.org/gmane.comp.lang.haskell.libraries/5622 ) seems 
compelling, too. Incidentally, the mail is form the thread in which the term 
Fairbairn threshold was coined.

- Frerich
Greg Weber | 18 Jul 21:57 2014

Re: Proposal: add 'equating' function to Data.List

I think the `By` functions that expect a Bool are all cumbersome because they are too flexible. 100% of the time I personally use these functions I want to use Ord or Eq.
What I would like to see is a function groupOn next to groupBy.

groupOn :: Eq b => (a -> b) -> [a] -> [[a]]

Then equating is no longer needed, and one just writes: groupOn snd
I believe this style also gives better opportunity for optimization (Scwartzian transform).

Of course, this function is still problematic because it operates only on lists and does not group over the entire list, but those are separate issues.
All of this is solved in mono-traversable right now by the groupAllOn function [1]



On Fri, Jul 18, 2014 at 12:26 PM, Frerich Raabe <raabe <at> froglogic.com> wrote:
Hi,

A common use case for 'on' (from Data.Function) is to use it with 'compare', e.g. 'compare `on` snd'. In fact, this pattern is so common that there's a convenient 'comparing' function which provides a shortcut for this use case such that one can write

  sortBy (comparing snd)

instead of

  sortBy (compare `on` snd)

I think another common use case is to use 'on' together with (==) as in

  groupBy ((==) `on` snd)

In a similiar vein as with 'comparing', I think it would be nice if there was a function which encapsulates this use case, like

  equating :: Eq b => (a -> b) -> a -> a -> Bool
  equating = on (==)

such that one can write

  groupBy (equating snd)

In fact, groupBy is just one of many *By functions taking an a -> a -> Bool -- many of which are Data.List, e.g. groupBy, nubBy, deleteBy, intersectBy, unionBy. Hence, it seems plausible to define 'equating' in Data.List. This is the same reasoning as why 'comparing' is in Data.Ord: because the module exposes a lot of *By functions taking an a -> a -> Ordering.

- Frerich

_______________________________________________
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
Henning Thielemann | 18 Jul 22:07 2014
Picon

Re: Proposal: add 'equating' function to Data.List

Am 18.07.2014 21:57, schrieb Greg Weber:

> I think the `By` functions that expect a Bool are all cumbersome because
> they are too flexible. 100% of the time I personally use these functions
> I want to use Ord or Eq.
> What I would like to see is a function groupOn next to groupBy.
>
> groupOn :: Eq b => (a -> b) -> [a] -> [[a]]
>
> Then equating is no longer needed, and one just writes: groupOn snd
> I believe this style also gives better opportunity for optimization
> (Scwartzian transform).

It's also in my utility package:

http://hackage.haskell.org/package/utility-ht-0.0.10/docs/Data-List-Key.html

I have also a version of 'groupBy' that returns a list of non-empty lists:

http://hackage.haskell.org/package/non-empty-0.2/docs/Data-NonEmpty-Mixed.html#v:groupBy

It's all Haskell 98.
Greg Weber | 18 Jul 22:28 2014

Re: Proposal: add 'equating' function to Data.List



On Fri, Jul 18, 2014 at 1:07 PM, Henning Thielemann <schlepptop <at> henning-thielemann.de> wrote:
Am 18.07.2014 21:57, schrieb Greg Weber:


I think the `By` functions that expect a Bool are all cumbersome because
they are too flexible. 100% of the time I personally use these functions
I want to use Ord or Eq.
What I would like to see is a function groupOn next to groupBy.

groupOn :: Eq b => (a -> b) -> [a] -> [[a]]

Then equating is no longer needed, and one just writes: groupOn snd
I believe this style also gives better opportunity for optimization
(Scwartzian transform).

It's also in my utility package:

http://hackage.haskell.org/package/utility-ht-0.0.10/docs/Data-List-Key.html

I have also a version of 'groupBy' that returns a list of non-empty lists:

http://hackage.haskell.org/package/non-empty-0.2/docs/Data-NonEmpty-Mixed.html#v:groupBy


non-empty looks nice! semigroups has groupBy1 now that returns NonEmpty

It's all Haskell 98.


You should add mono-traversable (Data.MinLen) [1] to your compariisons. It should be a lot more efficient when tracking length beyond 1 element, but it is definitely not Haskell 98.

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Greg Weber | 21 Jul 02:27 2014

Re: Proposal: add 'equating' function to Data.List

I am -1 on things that encourage converting Eq to Bool rather than just using Eq directly.

Is there a use case for group that is not satisfied by groupOn with a newtype with an Eq instance?
Granted, a newtype may be heavy-weight, but I feel that the current group should be an escape hatch in the rare case that groupOn does not suffice, not something we codify via Fairbairn threshold because that is the only API that exists today. I can create a separate proposal for adding groupOn, etc.


On Fri, Jul 18, 2014 at 12:57 PM, Greg Weber <greg <at> gregweber.info> wrote:
I think the `By` functions that expect a Bool are all cumbersome because they are too flexible. 100% of the time I personally use these functions I want to use Ord or Eq.
What I would like to see is a function groupOn next to groupBy.

groupOn :: Eq b => (a -> b) -> [a] -> [[a]]

Then equating is no longer needed, and one just writes: groupOn snd
I believe this style also gives better opportunity for optimization (Scwartzian transform).

Of course, this function is still problematic because it operates only on lists and does not group over the entire list, but those are separate issues.
All of this is solved in mono-traversable right now by the groupAllOn function [1]



On Fri, Jul 18, 2014 at 12:26 PM, Frerich Raabe <raabe <at> froglogic.com> wrote:
Hi,

A common use case for 'on' (from Data.Function) is to use it with 'compare', e.g. 'compare `on` snd'. In fact, this pattern is so common that there's a convenient 'comparing' function which provides a shortcut for this use case such that one can write

  sortBy (comparing snd)

instead of

  sortBy (compare `on` snd)

I think another common use case is to use 'on' together with (==) as in

  groupBy ((==) `on` snd)

In a similiar vein as with 'comparing', I think it would be nice if there was a function which encapsulates this use case, like

  equating :: Eq b => (a -> b) -> a -> a -> Bool
  equating = on (==)

such that one can write

  groupBy (equating snd)

In fact, groupBy is just one of many *By functions taking an a -> a -> Bool -- many of which are Data.List, e.g. groupBy, nubBy, deleteBy, intersectBy, unionBy. Hence, it seems plausible to define 'equating' in Data.List. This is the same reasoning as why 'comparing' is in Data.Ord: because the module exposes a lot of *By functions taking an a -> a -> Ordering.

- Frerich

_______________________________________________
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
John Lato | 21 Jul 02:46 2014
Picon

Re: Proposal: add 'equating' function to Data.List

The utility of the proposed "equating" extends far beyond simply using it with groupBy.  Just last week I used "on (==)" as part of a complicated boolean expression.

That said, I just want to be clear that I'm understanding Greg properly.  Are you advocating that one should generally create a newtype+Eq instance rather than using "on (==)"?  What is the benefit of this approach?  The only one I can think of is that it makes the standard libraries smaller, which seems like a rather small gain considering that you've changed a 7-character expression into multi-line boilerplate for everyone, hampering readability in the process.  Is there something I'm missing here?

(Currently +0 on the proposal)

John L.


On Mon, Jul 21, 2014 at 8:27 AM, Greg Weber <greg <at> gregweber.info> wrote:
I am -1 on things that encourage converting Eq to Bool rather than just using Eq directly.

Is there a use case for group that is not satisfied by groupOn with a newtype with an Eq instance?
Granted, a newtype may be heavy-weight, but I feel that the current group should be an escape hatch in the rare case that groupOn does not suffice, not something we codify via Fairbairn threshold because that is the only API that exists today. I can create a separate proposal for adding groupOn, etc.


On Fri, Jul 18, 2014 at 12:57 PM, Greg Weber <greg <at> gregweber.info> wrote:
I think the `By` functions that expect a Bool are all cumbersome because they are too flexible. 100% of the time I personally use these functions I want to use Ord or Eq.
What I would like to see is a function groupOn next to groupBy.

groupOn :: Eq b => (a -> b) -> [a] -> [[a]]

Then equating is no longer needed, and one just writes: groupOn snd
I believe this style also gives better opportunity for optimization (Scwartzian transform).

Of course, this function is still problematic because it operates only on lists and does not group over the entire list, but those are separate issues.
All of this is solved in mono-traversable right now by the groupAllOn function [1]



On Fri, Jul 18, 2014 at 12:26 PM, Frerich Raabe <raabe <at> froglogic.com> wrote:
Hi,

A common use case for 'on' (from Data.Function) is to use it with 'compare', e.g. 'compare `on` snd'. In fact, this pattern is so common that there's a convenient 'comparing' function which provides a shortcut for this use case such that one can write

  sortBy (comparing snd)

instead of

  sortBy (compare `on` snd)

I think another common use case is to use 'on' together with (==) as in

  groupBy ((==) `on` snd)

In a similiar vein as with 'comparing', I think it would be nice if there was a function which encapsulates this use case, like

  equating :: Eq b => (a -> b) -> a -> a -> Bool
  equating = on (==)

such that one can write

  groupBy (equating snd)

In fact, groupBy is just one of many *By functions taking an a -> a -> Bool -- many of which are Data.List, e.g. groupBy, nubBy, deleteBy, intersectBy, unionBy. Hence, it seems plausible to define 'equating' in Data.List. This is the same reasoning as why 'comparing' is in Data.Ord: because the module exposes a lot of *By functions taking an a -> a -> Ordering.

- Frerich

_______________________________________________
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


_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
David Feuer | 21 Jul 02:52 2014
Picon

Re: Proposal: add 'equating' function to Data.List

Eq instances should only be used for conceptual equality, and never just for convenience applying some function or other. I don't think that makes any sort of argument for "equating", though.

On Jul 20, 2014 8:46 PM, "John Lato" <jwlato <at> gmail.com> wrote:
The utility of the proposed "equating" extends far beyond simply using it with groupBy.  Just last week I used "on (==)" as part of a complicated boolean expression.

That said, I just want to be clear that I'm understanding Greg properly.  Are you advocating that one should generally create a newtype+Eq instance rather than using "on (==)"?  What is the benefit of this approach?  The only one I can think of is that it makes the standard libraries smaller, which seems like a rather small gain considering that you've changed a 7-character expression into multi-line boilerplate for everyone, hampering readability in the process.  Is there something I'm missing here?

(Currently +0 on the proposal)

John L.


On Mon, Jul 21, 2014 at 8:27 AM, Greg Weber <greg <at> gregweber.info> wrote:
I am -1 on things that encourage converting Eq to Bool rather than just using Eq directly.

Is there a use case for group that is not satisfied by groupOn with a newtype with an Eq instance?
Granted, a newtype may be heavy-weight, but I feel that the current group should be an escape hatch in the rare case that groupOn does not suffice, not something we codify via Fairbairn threshold because that is the only API that exists today. I can create a separate proposal for adding groupOn, etc.


On Fri, Jul 18, 2014 at 12:57 PM, Greg Weber <greg <at> gregweber.info> wrote:
I think the `By` functions that expect a Bool are all cumbersome because they are too flexible. 100% of the time I personally use these functions I want to use Ord or Eq.
What I would like to see is a function groupOn next to groupBy.

groupOn :: Eq b => (a -> b) -> [a] -> [[a]]

Then equating is no longer needed, and one just writes: groupOn snd
I believe this style also gives better opportunity for optimization (Scwartzian transform).

Of course, this function is still problematic because it operates only on lists and does not group over the entire list, but those are separate issues.
All of this is solved in mono-traversable right now by the groupAllOn function [1]



On Fri, Jul 18, 2014 at 12:26 PM, Frerich Raabe <raabe <at> froglogic.com> wrote:
Hi,

A common use case for 'on' (from Data.Function) is to use it with 'compare', e.g. 'compare `on` snd'. In fact, this pattern is so common that there's a convenient 'comparing' function which provides a shortcut for this use case such that one can write

  sortBy (comparing snd)

instead of

  sortBy (compare `on` snd)

I think another common use case is to use 'on' together with (==) as in

  groupBy ((==) `on` snd)

In a similiar vein as with 'comparing', I think it would be nice if there was a function which encapsulates this use case, like

  equating :: Eq b => (a -> b) -> a -> a -> Bool
  equating = on (==)

such that one can write

  groupBy (equating snd)

In fact, groupBy is just one of many *By functions taking an a -> a -> Bool -- many of which are Data.List, e.g. groupBy, nubBy, deleteBy, intersectBy, unionBy. Hence, it seems plausible to define 'equating' in Data.List. This is the same reasoning as why 'comparing' is in Data.Ord: because the module exposes a lot of *By functions taking an a -> a -> Ordering.

- Frerich

_______________________________________________
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



_______________________________________________
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
Greg Weber | 21 Jul 03:38 2014

Re: Proposal: add 'equating' function to Data.List




On Sun, Jul 20, 2014 at 5:46 PM, John Lato <jwlato <at> gmail.com> wrote:
The utility of the proposed "equating" extends far beyond simply using it with groupBy.  Just last week I used "on (==)" as part of a complicated boolean expression.

That said, I just want to be clear that I'm understanding Greg properly.  Are you advocating that one should generally create a newtype+Eq instance rather than using "on (==)"?  What is the benefit of this approach?  The only one I can think of is that it makes the standard libraries smaller, which seems like a rather small gain considering that you've changed a 7-character expression into multi-line boilerplate for everyone, hampering readability in the process.  Is there something I'm missing here?

Sorry I didn't do a good job explaining. groupOn takes a function that is a projection to an equality instance (Eq b => (a -> b)).
So there is no need for a newtype, and this interface has suited 100% of my needs, and every usage I have ever seen in Haskell code.

My presumption is that the only reason this interface is not 100% satisfactory and we have this weird interface based on Bool is because you may want to compare something that does not have an Eq instance. One could still handle that case by wrapping the projected value in a newtype and writing an Eq instance for that newtype.


(Currently +0 on the proposal)

John L.


On Mon, Jul 21, 2014 at 8:27 AM, Greg Weber <greg <at> gregweber.info> wrote:
I am -1 on things that encourage converting Eq to Bool rather than just using Eq directly.

Is there a use case for group that is not satisfied by groupOn with a newtype with an Eq instance?
Granted, a newtype may be heavy-weight, but I feel that the current group should be an escape hatch in the rare case that groupOn does not suffice, not something we codify via Fairbairn threshold because that is the only API that exists today. I can create a separate proposal for adding groupOn, etc.


On Fri, Jul 18, 2014 at 12:57 PM, Greg Weber <greg <at> gregweber.info> wrote:
I think the `By` functions that expect a Bool are all cumbersome because they are too flexible. 100% of the time I personally use these functions I want to use Ord or Eq.
What I would like to see is a function groupOn next to groupBy.

groupOn :: Eq b => (a -> b) -> [a] -> [[a]]

Then equating is no longer needed, and one just writes: groupOn snd
I believe this style also gives better opportunity for optimization (Scwartzian transform).

Of course, this function is still problematic because it operates only on lists and does not group over the entire list, but those are separate issues.
All of this is solved in mono-traversable right now by the groupAllOn function [1]



On Fri, Jul 18, 2014 at 12:26 PM, Frerich Raabe <raabe <at> froglogic.com> wrote:
Hi,

A common use case for 'on' (from Data.Function) is to use it with 'compare', e.g. 'compare `on` snd'. In fact, this pattern is so common that there's a convenient 'comparing' function which provides a shortcut for this use case such that one can write

  sortBy (comparing snd)

instead of

  sortBy (compare `on` snd)

I think another common use case is to use 'on' together with (==) as in

  groupBy ((==) `on` snd)

In a similiar vein as with 'comparing', I think it would be nice if there was a function which encapsulates this use case, like

  equating :: Eq b => (a -> b) -> a -> a -> Bool
  equating = on (==)

such that one can write

  groupBy (equating snd)

In fact, groupBy is just one of many *By functions taking an a -> a -> Bool -- many of which are Data.List, e.g. groupBy, nubBy, deleteBy, intersectBy, unionBy. Hence, it seems plausible to define 'equating' in Data.List. This is the same reasoning as why 'comparing' is in Data.Ord: because the module exposes a lot of *By functions taking an a -> a -> Ordering.

- Frerich

_______________________________________________
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



_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
John Lato | 21 Jul 03:53 2014
Picon

Re: Proposal: add 'equating' function to Data.List

On Mon, Jul 21, 2014 at 9:38 AM, Greg Weber <greg <at> gregweber.info> wrote:

On Sun, Jul 20, 2014 at 5:46 PM, John Lato <jwlato <at> gmail.com> wrote:
The utility of the proposed "equating" extends far beyond simply using it with groupBy.  Just last week I used "on (==)" as part of a complicated boolean expression.

That said, I just want to be clear that I'm understanding Greg properly.  Are you advocating that one should generally create a newtype+Eq instance rather than using "on (==)"?  What is the benefit of this approach?  The only one I can think of is that it makes the standard libraries smaller, which seems like a rather small gain considering that you've changed a 7-character expression into multi-line boilerplate for everyone, hampering readability in the process.  Is there something I'm missing here?

Sorry I didn't do a good job explaining. groupOn takes a function that is a projection to an equality instance (Eq b => (a -> b)).
So there is no need for a newtype, and this interface has suited 100% of my needs, and every usage I have ever seen in Haskell code.

My presumption is that the only reason this interface is not 100% satisfactory and we have this weird interface based on Bool is because you may want to compare something that does not have an Eq instance. One could still handle that case by wrapping the projected value in a newtype and writing an Eq instance for that newtype.

I see, thanks for the explanation.  Seems like a reasonable function IMHO.

It still isn't a full replacement for equating though.  In my case, I used "if on (==) someLongSelector a b then ..." to save some characters over the obvious alternative.
_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
David Feuer | 18 Jul 23:19 2014
Picon

Re: Proposal: add 'equating' function to Data.List

What I'd like for Data.List is

uncons :: [a] -> Maybe (a, [a]).
uncons [] = Nothing
uncons (a:as) = Just (a,as)

I believe Data.Text and maybe even Data.ByteString have similar functions. The main reason, I think:

The idiom

do
  x <- listToMaybe xss
  ...
  ... tail xss
  ...

is a bit ugly as the safety of tail xs depends implicitly on the fact that listToMaybe guards it, and because it treats the head and tail completely differently. Far prettier:

do
  (x,xs) <- uncons xss
  ...

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Henning Thielemann | 18 Jul 23:23 2014
Picon

Data.List.viewL (was: Proposal: add 'equating' function to Data.List)

Am 18.07.2014 23:19, schrieb David Feuer:

> What I'd like for Data.List is
>
> uncons :: [a] -> Maybe (a, [a]).
> uncons [] = Nothing
> uncons (a:as) = Just (a,as)
>
> I believe Data.Text and maybe even Data.ByteString have similar
> functions.

I called it viewL, analogously to Data.Sequence:

http://hackage.haskell.org/package/utility-ht-0.0.10/docs/Data-List-HT.html#v:viewL
Edward Kmett | 19 Jul 15:10 2014
Picon

Re: Proposal: add 'equating' function to Data.List

Put in a separate proposal for Data.List.uncons. It is a reasonable, self-contained function that encourages good style. The name has been commonly used and reinvented over and over and as a top level proposal we can have any bikeshedding discussion without derailing this one.

I honestly thought it was already in there.

-Edward

On Jul 18, 2014, at 5:19 PM, David Feuer <david.feuer <at> gmail.com> wrote:

What I'd like for Data.List is

uncons :: [a] -> Maybe (a, [a]).
uncons [] = Nothing
uncons (a:as) = Just (a,as)

I believe Data.Text and maybe even Data.ByteString have similar functions. The main reason, I think:

The idiom

do
  x <- listToMaybe xss
  ...
  ... tail xss
  ...

is a bit ugly as the safety of tail xs depends implicitly on the fact that listToMaybe guards it, and because it treats the head and tail completely differently. Far prettier:

do
  (x,xs) <- uncons xss
  ...

_______________________________________________
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
Alexander Berntsen | 19 Jul 12:54 2014
Picon

Re: Proposal: add 'equating' function to Data.List


-1 because I'm not convinced this belongs in Data.List. comparing is
in Data.Ord and is:

Data.Ord comparing :: Ord a => (b -> a) -> b -> b -> Ordering

So equating should be in Data.Eq, with:

equating :: Eq a => (b -> a) -> b -> b -> Bool

Furthermore I do not like your definition, and would prefer:

equating p x y = (p x) == (p y)

With these issues amended, I'm 0 on the proposal.
--

-- 
Alexander
alexander <at> plaimi.net
https://secure.plaimi.net/~alexander
Ivan Lazar Miljenovic | 19 Jul 13:44 2014
Picon

Re: Proposal: add 'equating' function to Data.List

On 19 July 2014 20:54, Alexander Berntsen <alexander <at> plaimi.net> wrote:
> Furthermore I do not like your definition, and would prefer:
>
> equating p x y = (p x) == (p y)

How is this any different from the original proposed solution?

Either way, it's -1 for the proposal from me as well.

--

-- 
Ivan Lazar Miljenovic
Ivan.Miljenovic <at> gmail.com
http://IvanMiljenovic.wordpress.com
Alexander Berntsen | 19 Jul 14:15 2014
Picon

Re: Proposal: add 'equating' function to Data.List


On 19/07/14 13:44, Ivan Lazar Miljenovic wrote:
>> equating p x y = (p x) == (p y)
> How is this any different from the original proposed solution?
I'm not sure what you mean. Is it not obvious? The original proposal
is defined in terms of on. Mine is not.

--

-- 
Alexander
alexander <at> plaimi.net
https://secure.plaimi.net/~alexander
Ivan Lazar Miljenovic | 19 Jul 15:52 2014
Picon

Re: Proposal: add 'equating' function to Data.List

On 19 July 2014 22:15, Alexander Berntsen <alexander <at> plaimi.net> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> On 19/07/14 13:44, Ivan Lazar Miljenovic wrote:
>>> equating p x y = (p x) == (p y)
>> How is this any different from the original proposed solution?
> I'm not sure what you mean. Is it not obvious? The original proposal
> is defined in terms of on. Mine is not.

I meant more along the lines of why is this any better than using on.

--

-- 
Ivan Lazar Miljenovic
Ivan.Miljenovic <at> gmail.com
http://IvanMiljenovic.wordpress.com
Alexander Berntsen | 19 Jul 15:54 2014
Picon

Re: Proposal: add 'equating' function to Data.List


On 19/07/14 15:52, Ivan Lazar Miljenovic wrote:
> I meant more along the lines of why is this any better than using 
> on.
Ah, I see. To avoid importing 'on' into 'Data.Eq'. and because it is
symmetrical with how 'comparing' is already defined in 'Data.Ord'.
--

-- 
Alexander
alexander <at> plaimi.net
https://secure.plaimi.net/~alexander
Frerich Raabe | 20 Jul 12:51 2014

Re: Proposal: add 'equating' function to Data.List

On 2014-07-18 21:26, Frerich Raabe wrote:
> In a similiar vein as with 'comparing', I think it would be nice if there 
> was a function which encapsulates this use case, like
>
>   equating :: Eq b => (a -> b) -> a -> a -> Bool
>   equating = on (==)
>
> such that one can write
>
>   groupBy (equating snd)

I don't know whether this is relevant to the decision making process, but it 
appears there's some precedence already in the 'basic-prelude' package by Dan 
Burton and Michael Snoyman: the 'CorePrelude' module exposes an 'equating' 
function:

   
https://hackage.haskell.org/package/basic-prelude-0.3.8/docs/CorePrelude.html#v:equating

- Frerich
Herbert Valerio Riedel | 20 Jul 23:25 2014
Picon

Re: Proposal: add 'equating' function to Data.List

On 2014-07-18 at 21:26:16 +0200, Frerich Raabe wrote:

[...]

> In fact, this pattern is so common that there's a convenient
> 'comparing' function which provides a shortcut for this use case

btw, you got the history/causality backwards in your argument: afaik,
'comparing' predates 'on', and removing the existing function
'comparing' would have been a backward incompatible change.

[...]

> In fact, groupBy is just one of many *By functions taking an a -> a ->
> Bool -- many of which are Data.List, e.g. groupBy, nubBy, deleteBy,
> intersectBy, unionBy. Hence, it seems plausible to define 'equating'
> in Data.List. 

> This is the same reasoning as why 'comparing' is in Data.Ord: because
> the module exposes a lot of *By functions taking an a -> a ->
> Ordering.

I don't see in what way 'equating' belonging in "Data.List" poses the
"the same reasoning" of 'comparing' being in "Data.Ord". This would
rather call for 'equating' belonging in "Data.Eq" (which is actually a
module that's almost never imported explicitly).

Consequently, I'm -1 on adding 'equating' to Data.List.

However, I'm generally -0.5 on adding 'equating', as I'm not convinced
'equating' provides any significant benefit over "on (==)" (whose only
downside to me is that it requires an additional "import Data.Function")
I'd rather improve the existing documentation in Data.List to provide
code examples involving the use of `on` for the most common tasks.

Cheers,
  hvr
Alexander Berntsen | 20 Jul 23:48 2014
Picon

Re: Proposal: add 'equating' function to Data.List


On 20/07/14 23:25, Herbert Valerio Riedel wrote:
> I'm not convinced 'equating' provides any significant benefit over 
> "on (==)"
It doesn't.

Thus my initial gut reaction of +0. But I agree with Edward's proposed
co-fairbairn threshold, putting me at +1.

--

-- 
Alexander
alexander <at> plaimi.net
https://secure.plaimi.net/~alexander
Eric Mertens | 21 Jul 02:14 2014
Picon

Re: Proposal: add 'equating' function to Data.List

I'm -1 on adding equating to base. I don't think it improves over using `on` or even just a locally defined function or lambda and just adds another name to learn.

If we do have it I'm also against it going into Data.List, and I would prefer Data.Eq.

I'm quite happy to have this proposal come up again in a few months and direct that discussion back to the archive.

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

Gmane