decir que queremos hacer una función como minBy
que devuelve todos los elementos de igual minimalismo en una colección:Volviendo tipo de colección original en método genérico
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)
Hasta ahora, todo bien, excepto que tenemos una Traversable
vuelta en lugar de nuestra inicial List
.
así que he intentado cambiar la firma a
def multiMinBy[A, B: Ordering, C <: Traversable[A]](xs: C)(f: A => B)
con la esperanza de que podría conseguir un C
atrás en lugar de un Traversable[A]
. Sin embargo, no recibo nada a cambio:
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]]
Creo que esto es porque tenemos C
que aparecen en los argumentos antes A
ha deducido? Así que me da la vuelta al orden de los argumentos, y añadí un reparto:
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]
}
que funciona, excepto que tenemos que llamarlo así:
multiMinBy((x: String) => x.last)(List("zza","zzza","zzb","zzzb"))
¿Hay una manera de conservar la sintaxis original, mientras recuperas el tipo de colección correcto?
Sí, estoy de acuerdo, esta es una solución mejor que la mía. –