In this post we’ll look at how to implement ordering using Scalaz `Order`

trait. However, before we do that, let’s step back a little and look at how we implement ordering using `scala.math.Ordering`

## Sorting a Collection - Scala Way

Say we have a `List`

and we’d like to sort it.^{[1]} We can do so by calling the `sorted`

method on it and it’ll work out-of-the-box for lists of `Int`

, `Float`

, etc. because there is an implicit in `scala.math.Ordering`

.

1 | @ List(1, 2, 3, 5, 4, 10, -1, 0).sorted |

Going over the documentation for `scala.math.Ordering`

^{[2]}:

*Ordering is a trait whose instances each represent a strategy for sorting instances of a type.Ordering’s companion object defines many implicit objects to deal with subtypes of AnyVal (e.g. Int, Double), String, and others.*

All the implicit objects in the companion object implement the `scala.math.Ordering`

trait which extends the `java.util.Comparator`

interface. Thus, they all have a `compare`

method. What if we have types for which there is no sorting strategy in the companion object of `scala.math.Ordering`

? We define our own like so:

1 | @ case class Salary(amt: Float) |

But we still don’t have operators like `<`

, `<=`

, etc. on type `Salary`

.

1 | @ Salary(999.0f) > Salary(555.0f) |

To do that, the trait `scala.math.Ordered`

would have to be mixed in.

1 | @ case class Salary(amt: Float) extends Ordered[Salary] { |

And we know that if we’re working with a library, we do not have the liberty to mix a trait for our convenience. Also, Scala’s comparison operators are not type safe.

1 | @ 1 > 2.0 |

## Sorting a Collection - Scalaz Way

As stated before, Scalaz provides `Order`

trait. Staying with our `Salary`

example, let’s put Scalaz `Order`

to use.

1 | @ import scalaz._ |

We’ve defined a way to order `Salary`

objects using Scalaz `Order`

trait via a typeclass. The implicit object needs to provide an implementation for `order`

method which returns an `Ordering`

value. Going over the code for Scalaz `Ordering`

:

*This Ordering is analogous to the Ints returned by scala.math.Ordering.*

Now, we have comparison operators at our disposal. Here’s how we can compare `Salary`

objects using the `?|?`

operator:

1 | @ Salary(1.0f) ?|? Salary(2.0f) |

`?|?`

can also be used with `Int`

, `Float`

, etc. and is type-safe.

1 | @ 1.0 ?|? 2.0 |

Also, analogous to `<`

, `<=`

, we now have type-safe `lt`

, `lte`

, etc.

1 | @ 1.0 gte 2.0 |

That’s not where the power ends. You can also compare `Option`

s seamlessly. Do note that it is `some`

with a lowercase “s”.

1 | @ some(Salary(1.0f)) ?|? some(Salary(2.0f)) |

You can now also use `sorted`

on a collection equally easily. Using `Order[A].toScalaOrdering`

we can get back an object of type `scala.math.Ordering`

which we can use to sort collections.

1 | @ implicit val salaryOrdering = Order[Salary].toScalaOrdering |

Also, since `Order`

trait extends the `Equal`

trait, you get the `===`

operator, too.

1 | @ Salary(0.0F) === Salary(1.0F) |

## Conclusion

By using Scalaz `Order`

trait, we can implement comparison between values in a type-safe and extensible way. There’s seamless transformation from Scalaz `Order`

to `scala.math.Ordering`

which lets us use the `sorted`

method on collections.