Skip to content

Instantly share code, notes, and snippets.

@derekjw
Created August 16, 2011 16:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derekjw/1149463 to your computer and use it in GitHub Desktop.
Save derekjw/1149463 to your computer and use it in GitHub Desktop.
Contravariant Ordering
trait Foo {
def value: Int
}
class Bar(val value: Int) extends Foo
class Baz(val value: Int) extends Foo
trait Foo2[-A] extends Foo
class Bar2(val value: Int) extends Foo2[Bar]
class Baz2(val value: Int) extends Foo2[Baz]
implicit val ordFoo = new Ordering[Foo] {
def compare(x: Foo, y: Foo) = {
println("Ordering[Foo]")
x.value - y.value
}
}
implicit val ordBar = new Ordering[Bar] {
def compare(x: Bar, y: Bar) = {
println("Ordering[Bar]")
x.value - y.value
}
}
implicit val ordFoo2Bar = new Ordering[Foo2[Foo]] {
def compare(x: Foo2[Foo], y: Foo2[Foo]) = {
println("Ordering[Foo2[Foo]]")
x.value - y.value
}
}
implicit val ordFoo2Baz = new Ordering[Foo2[Baz]] {
def compare(x: Foo2[Baz], y: Foo2[Baz]) = {
println("Ordering[Foo2[Baz]]")
x.value - y.value
}
}
implicit def contraOrdering[A](implicit ord: Ordering[_ >: A]): Ordering[A] = ord.asInstanceOf[Ordering[A]]
class OrderingOps[A](lhs: A) {
def <[B >: A](rhs: B)(implicit ord: Ordering[B]) = ord.lt(lhs, rhs)
def <=[B >: A](rhs: B)(implicit ord: Ordering[B]) = ord.lteq(lhs, rhs)
def >[B >: A](rhs: B)(implicit ord: Ordering[B]) = ord.gt(lhs, rhs)
def >=[B >: A](rhs: B)(implicit ord: Ordering[B]) = ord.gteq(lhs, rhs)
def equiv[B >: A](rhs: B)(implicit ord: Ordering[B]) = ord.equiv(lhs, rhs)
def max[B >: A](rhs: B)(implicit ord: Ordering[B]): B = ord.max(lhs, rhs)
def min[B >: A](rhs: B)(implicit ord: Ordering[B]): B = ord.min(lhs, rhs)
}
implicit def orderingOps[A](value: A) = new OrderingOps(value)
val bar1 = new Bar(3)
val bar2 = new Bar(2)
val baz = new Baz(5)
val foo = new Foo { val value = 4 }
print("Comparing Bar < Bar = ")
bar1 < bar2
print("Comparing Bar < Baz = ")
bar1 < baz
print("Comparing Foo < Baz = ")
foo < baz
print("Comparing Bar < Foo = ")
bar2 < foo
val foo2bar = new Bar2(1)
val foo2baz = new Baz2(2)
val foo2 = new Foo2[Foo] { val value: Int = 3 }
print("Comparing Bar2 < Baz2 = ")
foo2bar < foo2baz
print("Comparing Foo2 < Baz2 = ")
foo2 < foo2baz
print("Comparing Bar2 < Foo2 = ")
foo2bar < foo2
print("Comparing Foo2 < Foo2 = ")
foo2 < foo2
Comparing Bar < Bar = Ordering[Bar]
Comparing Bar < Baz = Ordering[Foo]
Comparing Foo < Baz = Ordering[Foo]
Comparing Bar < Foo = Ordering[Foo]
Comparing Bar2 < Baz2 = Ordering[Foo]
Comparing Foo2 < Baz2 = Ordering[Foo2[Baz]]
Comparing Bar2 < Foo2 = Ordering[Foo]
Comparing Foo2 < Foo2 = Ordering[Foo2[Foo]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment