Note: This post is written in literate Haskell. You can save it as Team.lhs
and try it. That being said, it's basically a longer version of Carsten's comment. If you still try to figure things out, use hoogle and look for the functions, although it's fine if you manage things with sortBy
solely first.
First of all, we're going to work on lists, so you want to import Data.List
.
> module Team where
> import Data.List
It contains a function called sortBy
:
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
The first argument of sortBy
should be a function that compares two elements of your list and returns
LT
if the first is less than the second,
EQ
if the both are equal,
GT
if the first is greater than the second.
So we need something that that takes two teams and returns their ordering:
> -- Repeating your types for completeness
> type TName = String
> type Points = [Int]
> type Team = (TName, Points)
>
> compareTeams :: Team -> Team -> Ordering
Now, you want to compare teams based on their sum of their points. You don't need their name, so you can capture just the second part of the pair:
> compareTeams (_, s1) (_, s2) =
We need the sum of the points, so we define sum1
and sum2
to be the respective sums of the teams:
> let sum1 = sum s1
> sum2 = sum s2
Now we can compare those sums:
in if sum1 < sum2
then LT
else if sum1 == sum2
then EQ
else GT
However, that's rather verbose, and there's already a function that has type Ord a => a -> a -> Ordering
. It's called compare
and part of the Prelude
:
> in sum1 `compare` sum2
That's a lot more concise. Now we can define sortTeams
easily:
> sortTeams :: [Team] -> [Team]
> sortTeams = sortBy compareTeams
And that's it, we're done!
Fine, I lied, we're not 100% done. The module Data.Ord
contains a function called comparing
that's rather handy:
comparing :: Ord b => (a -> b) -> a -> a -> Ordering
comparing f x y = f x `compare` f y -- or similar
Together with snd
and sum
you can define sortTeams
in a single line:
sortTeams = sortBy (comparing $ sum . snd)
The alternative on
mentioned by Carsten is on
from Data.Function
:
sortTeams = sortBy (compare `on` sum . snd)