开发者

Parameterized method with Ordering?

Now I am confused. I am quite new on Scala, having worked with it for a few weeks, I think I am getting familiar with it, but I am stuck on the appar开发者_如何学Pythonently trivial following case.

I cannot find the Scala equivalent to this Java declaration :

public static <T extends Comparable<T>> List<T> myMethod(List<T> values) {
  // ...
  final List<T> sorted = new ArrayList<T>(values);
  Collections.sort(sorted);
  // ...
}

I thought the following would do :

def myMethod[A >: Ordering[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}

However, I get the following errors:

error: illegal cyclic reference involving type A

error: diverging implicit expansion for type scala.math.Ordering[A] starting with method Tuple9 in object Ordering

Where am I wrong?


First of all, Ordering is akin to Comparator, not Comparable. The Scala equivalent to Comparable is Ordered. Next, extends equivalent is <:, not >:. The latter is equivalent to super -- T super COmparable<T>, which is not what you want. So, with both these fixes in, your code should look like this:

def myMethod[A <: Ordered[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}

However, this won't work for Seq[Int], for instance, since Int does not extend Ordered -- just like Java's int does not extend Comparable (or anything else, since it is not a class).

Scala has a work-around for that -- an implicit conversion from certain classes to an Ordered class. To use that, however, you need to use a view bound, which would make the code look like this:

def myMethod[A <% Ordered[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}

See <% instead of <:? That's the view bound.

Now, the current preference in Scala circles is to use context bounds instead of view bounds, as they are more flexible. That would mean using Ordering, in the manner described by the other answers.


That should be a context bound, as shown below.

scala> def myMethod[A : Ordering](values: Seq[A]): Seq[A] = values.sorted
myMethod: [A](values: Seq[A])(implicit evidence$1: Ordering[A])Seq[A]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜