Возврат исходного типа коллекции в универсальном методе

Допустим, мы хотим сделать функция вроде minBy , которая возвращает все элементы одинакового минимализма в коллекции:

def multiMinBy[A, B: Ordering](xs: Traversable[A])(f: A => B) = {
  val minVal = f(xs minBy f)
  xs filter (f(_) == minVal)
}

scala> multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last)
res33: Traversable[java.lang.String] = List(zza, zzza)

Пока все хорошо, за исключением того, что у нас есть Traversable назад вместо нашего исходного List .

Поэтому я попытался изменить подпись на

def multiMinBy[A, B: Ordering, C <: Traversable[A]](xs: C)(f: A => B)

в надежде получить обратно C , а не Traversable [A] . Однако я не получите ничего обратно:

scala> multiMinBy(List("zza","zzza","zzb","zzzb"))(_.last)

<console>:9: error: inferred type arguments [Nothing,Nothing,List[java.lang.String]] 
do not conform to method multiMinBy's type parameter bounds [A,B,C <: Traversable[A]]

Я думаю, это потому, что у нас есть C , появляющееся в аргументах до того, как A было выведено? Итак, я изменил порядок аргументов и добавлено приведение:

def multiMinBy[A, B: Ordering, C <: Traversable[A]](f: A => B)(xs: C) = {
  val minVal = f(xs minBy f)
  (xs filter (f(_) == minVal)).asInstanceOf[C]
}

, которое работает, за исключением того, что мы должны вызывать l это так:

multiMinBy((x: String) => x.last)(List("zza","zzza","zzb","zzzb"))

Есть ли способ сохранить исходный синтаксис и вернуть правильный тип коллекции?

19
задан Luigi a.k.a. Rhys 22 November 2011 в 23:38
поделиться