Reputation: 311
I have a function (frequency) which that counts how many times each distinct value in a list occurs in that list. For example,
frequency "ababca"
should return:
[(3, 'a'), (2, 'b'), (1, 'c')].
This works fine but now I need to sort the list using the first element within the list of the list using this function.
results :: [Party ] -> [(Int, Party)]
results xs = ??? frequency (sort xs) ???
example of desired output:
[(1, "Green"), (2, "Red"), (3, "Blue")]
The above does not work, I have no idea what I can do.
using regular 'sort'
Thank you in Advance.
Upvotes: 2
Views: 7654
Reputation: 58715
If you can only use sort
and not sortBy
(for some reason!) then you need to make sure that the items are of a type that is an instance of Ord
. As it happens, all tuples (up to size 15) have Ord
instances, provided that all the positions in the tuple also have Ord
instances.
The example you give of (1, "Green"), (2, "Red"), (3, "Blue")]
should sort fine (though reversed), since both Int
and String
have Ord
instances.
However, in the code snippet, you also mention a Party
type without actually saying what it is. If it's not just an alias for something like String, you may have to define an Ord
instance for it, to satisfy the built-in Ord instances for tuples.
You can have Haskell create instances for you, using deriving
when you declare the type
data Party = P1 | P2 | P3 | P4 -- e.g.
deriving (Eq,Ord)
or declare it yourself:
instance Ord Party where
-- you don't care about the ordering of the party values
compare a b = EQ
But, as dave4420 says, it's much better to just use sortBy
, so I would do that unless you have a specific reason not to (ie it's a class assignment with restrictions).
Upvotes: 2
Reputation: 47042
import Data.Function (on)
import Data.List (sortBy)
results xs = sortBy (compare `on` fst) (frequency xs)
-- or, if you prefer
results xs = sort (frequency xs)
Links to documentation for on
, sortBy
, compare
, fst
.
The difference is that sort
sorts in ascending order of the first element of each pair, breaking tie-breaks with the second elements of the pairs, while sortBy (compare `on` fst)
explicitly only looks at the first element of each pair.
Upvotes: 8