7

In haskell I can use

sortBy (comparing snd) 

to sort by the second value in a tuple.

Is there an equivalent function for testing equivalency? I've come up with this but maybe there is something in the standard library.

equalsBy :: Eq b => (a -> b) -> a -> a -> Bool
equalsBy f x y = f x == f y

The end goal is to group a list of pairs by their second values. With this I can do

groupBy (equalsBy snd) pairs

instead of

groupBy (\x y -> (snd x) == (snd y)) pairs
Erik Bergsten
  • 123
  • 1
  • 8

1 Answers1

17

You are looking for a slightly higher level function called on:

> import Data.Function
> :t on
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c

Well how do I use that? Like this!

> :t ( (==) `on` snd )
( (==) `on` snd ) :: Eq b => (a, b) -> (a, b) -> Bool

So that means we want:

> groupBy ( (==) `on` snd) [ (1,3), (23,9), (42,9), (1,3), (48, 3), (18,18)]
[[(1,3)],[(23,9),(42,9)],[(1,3),(48,3)],[(18,18)]]

Yay!

EDIT:

I'd like to note how comparing relates to on. It is just a specialized use of on!

> :t comparing
comparing      :: Ord a => (b -> a) -> b -> b -> Ordering
> :t (compare `on`)
(compare `on`) :: Ord b => (a -> b) -> a -> a -> Ordering

(notice the type variables are swapped, but you can see the types are identical)

mindthief
  • 12,755
  • 14
  • 57
  • 61
Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166
  • Also, `(compare \`on\`)` is the same as `on compare`. It doesn't sound quite as nice, but maybe makes the argument order of `on` a little more explicit. – David Young Jan 17 '14 at 02:36