Параметризованный метод с Ordering? - PullRequest
3 голосов
/ 31 мая 2011

Теперь я в замешательстве. Я довольно новичок в Scala, проработав с ним несколько недель, я думаю, что знакомлюсь с ним, но я застрял в явно тривиальном следующем случае.

Я не могу найти Scala, эквивалентный этому объявлению Java:

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

Я думал, что подойдет следующее:

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

Однако я получаю следующие ошибки:

ошибка: недопустимая циклическая ссылка с типом A

ошибка: неявное расширение для типа scala.math.Ordering [A] начиная с метода Tuple9 в объекте Ordering

Где я не прав?

Ответы [ 2 ]

7 голосов
/ 31 мая 2011

Прежде всего, Ordering сродни Comparator, а не Comparable.Scala, эквивалентный Comparable, равен Ordered.Далее extends эквивалент <:, а не >:.Последнее эквивалентно super - T super COmparable<T>, что не то, что вы хотите.Итак, с обоими этими исправлениями ваш код должен выглядеть следующим образом:

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

Однако это не сработает, например, для Seq[Int], поскольку Int не расширяет Ordered -- точно так же, как Java int не расширяет Comparable (или что-то еще, поскольку это не класс).

В Scala есть обходной путь - неявное преобразование определенных классов вOrdered класс.Однако, чтобы использовать это, вам нужно использовать границы представления , что бы код выглядел так:

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

См. <% вместо <:?Это граница вида.

Теперь в кругах Scala предпочтение отдается границам контекста вместо границ вида, поскольку они более гибкие.Это будет означать использование Ordering, как описано в других ответах.

5 голосов
/ 31 мая 2011

Это должна быть граница контекста, как показано ниже.

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