Skip to content

Instantly share code, notes, and snippets.

@retronym
Created November 5, 2011 23:33
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save retronym/1342196 to your computer and use it in GitHub Desktop.
Save retronym/1342196 to your computer and use it in GitHub Desktop.
Ordering thenBy
class RichOrdering[A](oa: Ordering[A]) {
def thenBy[B: Ordering](f: A => B): Ordering[A] = new Ordering[A] {
def compare(a1: A, a2: A) = oa.compare(a1, a2) match {
case 0 => Ordering[B].compare(f(a1), f(a2))
case x => x
}
}
}
implicit def ToRichOrdering[A](oa: Ordering[A]): RichOrdering[A] = new RichOrdering(oa)
case class Person(name: String, age: Int)
Ordering.by((_: Person).name).thenBy(_.age)
scala> import scalaz._, Scalaz._
scala> case class Person(name: String, age: Int)
defined class Person
scala> val byName = orderBy((_: Person).name)byName: scalaz.Order[Person] = scalaz.Orders$$anon$2@37cae761
scala> val byAge = orderBy((_: Person).age)
byAge: scalaz.Order[Person] = scalaz.Orders$$anon$2@64ad8f2b
// Should really come with Scalaz
// Order#compare returns Ordering; Semigroup[Ordering] provides
// lexicographical sorting:
// https://github.com/scalaz/scalaz/blob/6.0.3/core/src/main/scala/scalaz/Semigroup.scala#L44
scala> implicit def OrderSemigroup[A]: Semigroup[Order[A]] =
semigroup((o1, o2) => order((a1: A, a2: A) => o1.order(a1, a2) |+| o2.order(a1, a2)))
OrderingSemigroup: [A]=> scalaz.Semigroup[scalaz.Order[A]]
scala> val byAgeThenName = byAge |+| byName
byAgeThenName: scalaz.Order[Person] = scalaz.Orders$$anon$2@19163ae3
scala> byAgeThenName.order(Person("bob", 12), Person("bob", 13))
res5: scalaz.Ordering = LT
@jrwest
Copy link

jrwest commented Nov 9, 2011

Jason,

would you mind if I borrow this example (with credit of course) for learn you a scalaz? It would fit perfectly in the simple typeclasses section.

Jordan

@retronym
Copy link
Author

retronym commented Nov 9, 2011

Go for it.

I committed the type class instance for Semigroup[Order] to Scalaz master, too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment