5

我正在尝试编写一个函数,通过函数 F(我将其称为 F(S))映射序列 S,用 S 压缩结果值(F(S)),并按 F(S ),返回排序后的压缩值(我希望代码能清除这个,很难放入文本)

这是我当前的代码:

def sortByAndReturnZippedMetric[S,M<:Ordering[AnyVal]]( s:Seq[S], mapper:S=>M):Seq[(M,S)] =
s.map(mapper).zip(s).sortBy(_._1)

不过,Scalac 抱怨道:

error: diverging implicit expansion for type scala.math.Ordering[M]
starting with method comparatorToOrdering in trait LowPriorityOrderingImplicits
s.map(mapper).zip(s).sortBy(_._1)

                               ^

我会很感激一些关于可能出错的指示......

4

1 回答 1

6

Ordering是一个类型 class,这意味着如果您想捕获A以特定方式排序的事实,您只需将隐式实例Ordering[A]放入范围 - 您没有Aextend Ordering[A](或Ordering[AnyVal],等等)。

这种方法的优点是您可以使用特定类型的多个排序(尽管一次只能在一个类型的范围内使用一个隐式排序)。因此,例如,我可以编写以下内容:

scala> List(5, 2, 3, 1, 4).sorted
res0: List[Int] = List(1, 2, 3, 4, 5)

这里整数 () 的隐式排序Ordering.Int用作 的隐式参数sorted,但我们也可以显式传递不同的Ordering. 例如,我们可以通过反转隐含的顺序来创建新的顺序:

scala> List(5, 2, 3, 1, 4).sorted(Ordering.Int.reverse)
res1: List[Int] = List(5, 4, 3, 2, 1)

在您的情况下sortBy,正在寻找一个Ordering[Ordering[AnyVal]]不存在的 。您可以通过使用绑定来指示您需要订购的上下文来轻松解决此问题M,而不是M扩展Ordering[AnyVal]

def sortByZipped[S, M: Ordering](s: Seq[S], mapper: S => M): Seq[(M, S)] =
  s.map(mapper).zip(s).sortBy(_._1)

或者您可以跳过语法糖并使用隐式参数:

def sortByZipped[S, M](s: Seq[S], mapper: S => M)(implicit o: Ordering[M]) =
  s.map(mapper).zip(s).sortBy(_._1)(o)

这完全等同于上下文绑定的版本。

于 2012-11-25T23:07:44.203 回答