# A nice way of sorting

15 Jan 2022This blog post is to explore a really clean way of sorting a list in Haskell.

Suppose you have a type such as

```
data Person = Person
{ name :: String
, age :: Int
}
```

And you want to sort first by age, from older to younger, and then by name. A naive approach would be something like

```
comparePerson :: Person -> Person -> Ordering
comparePerson (Person name1 age1) (Person name2 age2)
| age1 > age2 = LT
| age1 < age2 = GT
| name1 > name2 = GT
| name1 < name2 = LT
| otherwise = EQ
```

And it pretty much works

```
lst = [ Person "A" 10
, Person "B" 20
, Person "B" 5
, Person "C" 10
]
sorted = sortBy comparePerson lst
-- Which is [ Person "B" 20
-- , Person "A" 10
-- , Person "C" 10
-- , Person "B" 5
-- ]
```

But the function is ugly, and quite error prone to write.
Enters the *semigroup instance* of `Ordering`

, which is defined as

```
instance Semigroup Ordering where
LT <> _ = LT
EQ <> y = y
GT <> _ = GT
```

We can then use `comparing`

from `Data.Ord`

with a couple of aliases and sort our list with
code that is simpler and clearer.

```
asc f = comparing f
desc f = flip (comparing f)
sorted = sortBy (desc age <> asc name) lst
```

Isn't that neat?