In the java.util.Collections class, we have two variants of the sort method, which accepts a list of arbitrary objects with the corresponding Comparator :
public static <T> void sort(List<T> list, Comparator<? super T> comparator)
And one that accepts a list of Comparable objects:
public static <T extends Comparable<? super T>> void sort(List<T> list)
I was thinking how to translate such restricted method wildcards into Scala. For the first version, I translated the signature literally and at a glance without compilation problems:
def sort[T](list: List[T], comparator: Comparator[_ >: T]) { ??? }
But then I found that I could not call this method with the following arguments:
val comparator = new Comparator[Object] { def compare(o1: Object, o2: Object) = ??? } val list = new ArrayList[Number] sort[Object](list, comparator)
The last line gives this compilation error, although I explicitly specify the type T as Object .
type mismatch; found: java.util.ArrayList [Number] required: java.util.List [Object] Note: Number <: Object, but the Java-defined list of attributes is invariant in type E. You can examine the type of wildcards, for example _ <: Object . (SLS 3.2.10)
In fact, I found out that it is not even possible to call a single Java method directly, since it fails with the same type of errors.
Collections.sort[Object](list, comparator)
As for the version with a comparable list, I came up with this announcement:
def sort[T <: Comparable[_ >: T]](list: List[T]) { ??? }
But this does not work at all:
illegal circular reference including type T
What am I doing wrong? Are Scala varieties of generics following various Java rules? How to call one call to the Collections.sort method without receiving a compilation error?
Side note:
No, I do not ask how to sort the list in Scala. I know that Scala has its own collection of collections, sorting functions, and a different approach to comparing objects (e.g. Ordered and Ordering ). My question is about the general problem of generic methods and translating generics from Java to Scala.