Scala 2.8 TreeMap and Custom Order

I am switching from scala 2.7 and ordering on scala 2.8 and using order. It looks straightforward, but I was wondering if I can make it a little less verbose. For example:

scala> case class A(i: Int) defined class A scala> object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i} defined module A 

If I try to create a TreeMap, I get an error

 scala> new collection.immutable.TreeMap[A, String]() <console>:10: error: could not find implicit value for parameter ordering: Ordering[A] new collection.immutable.TreeMap[A, String]() ^ 

However, if I explicitly specify object A as an order, it works fine.

 scala> new collection.immutable.TreeMap[A, String]()(A) res34: scala.collection.immutable.TreeMap[A,String] = Map() 

Should I always explicitly state the order or is there a shorter format?

thanks

+6
scala treemap order
source share
3 answers

Pay attention to the word "implicit" in the diagnosis. The parameter is declared implicit , which means that the compiler will try to find a suitable value in the scope at the point at which you invoke the constructor. If you make your order an implicit value, it will be entitled to this appeal by the compiler:

 scala> implicit object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i} defined module A scala> val tm1 = new collection.immutable.TreeMap[A, String]() tm1: scala.collection.immutable.TreeMap[A,String] = Map() 

Edit:

This example works in REPL because REPL wraps your code in invisible class definitions. Here is one that works freely:

 case class A(val i:Int) extends Ordered[A] { def compare(o:A) = i - oi } object A { implicit object AOrdering extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i } } class B { import A.AOrdering val tm1 = new collection.immutable.TreeMap[A, String]() } 
+10
source share

Keep in mind that there is a slightly less detailed way to create Ordering :

 implicit val OrderingA = Ordering.by((_: A).i) 

The main advantage of Ordering being is that you can provide many of them for the same class. If your class A really Ordered , then you should just extend it. If not, instead of using implications, you can explicitly pass the order:

 new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i)) 
+13
source share

Instead of expanding Ordering[A] try continuing with Ordered[A] . For example:

 scala> case class A(val i:Int) extends Ordered[A] {def compare(o:A) = io.i} defined class A scala> A(1)<A(2) res0: Boolean = true scala> A(1)<A(0) res1: Boolean = false scala> new collection.immutable.TreeMap[A, String]() res3: scala.collection.immutable.TreeMap[A,String] = Map() 
+5
source share

All Articles