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
Most notably, in Haskell, functions are not in the Eq typeclass (in general). Not any two functions can be compared for equality in Haskell.
Haskell provides a number of tests including: < (less than), > (greater than), <= (less than or equal to) and >= (greater than or equal to). These tests work comparably to == (equal to).
The == is an operator for comparing if two things are equal. It is quite normal haskell function with type "Eq a => a -> a -> Bool". The type tells that it works on every type of a value that implements Eq typeclass, so it is kind of overloaded.
Ord is a subclass of Eq that is used for data types that have a total ordering (every value can be compared with another).
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With