【发布时间】:2011-11-22 23:38:05
【问题描述】:
假设我们想要创建一个类似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]
}
这行得通,但我们必须这样称呼它:
multiMinBy((x: String) => x.last)(List("zza","zzza","zzb","zzzb"))
有没有办法在保留原始语法的同时恢复正确的集合类型?
【问题讨论】:
标签: generics scala collections