public
Created

automatic Ordering for case classes using shapeless

  • Download Gist
ShapelessOrdering.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
package shapeless
 
import shapeless._
import HList._
 
package object autoordering extends App {
 
type Iso[T, L <: HList] = HListIso[T, L]
 
implicit def ccOrdering[C, L <: HList](implicit iso: Iso[C, L], L: Ordering[L]) = new Ordering[C] {
def compare(x: C, y: C) = L.compare(iso.toHList(x), iso.toHList(y))
}
 
implicit def hnilOrdering: Ordering[HNil] = new Ordering[HNil] {
def compare(x: HNil, y: HNil) = 0
}
 
implicit def hlistOrdering[H, T <: HList](implicit H : Ordering[H], T : Ordering[T]) : Ordering[H :: T] = new Ordering[H :: T] {
def compare(x: H :: T, y: H :: T) = {
val hcmp = H.compare(x.head, y.head)
if (hcmp == 0) T.compare(x.tail, y.tail)
else hcmp
}
}
 
// A pair of arbitrary case classes
case class Foo(i : Int, s : String)
case class Bar(b : Boolean, s : String, d : Double)
 
// Publish their `HListIso`'s
implicit def fooIso = HListIso(Foo.apply _, Foo.unapply _)
implicit def barIso = HListIso(Bar.apply _, Bar.unapply _)
 
// And they have orderings
 
val fooOrd = implicitly[Ordering[Foo]]
assert(fooOrd.compare(Foo(1, "A"), Foo(0, "A")) > 0)
assert(fooOrd.compare(Foo(0, "A"), Foo(0, "A")) == 0)
assert(fooOrd.compare(Foo(0, "A"), Foo(0, "B")) < 0)
assert(fooOrd.compare(Foo(0, "C"), Foo(0, "B")) > 0)
 
println("Done")
//
//
//
 
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.