5

シーケンスSを関数F(F(S)と呼びます)でマップし、結果の値(F(S))をSで圧縮し、結果をF(S)で並べ替える関数を作成しようとしています。 )、ソートされたzip値を返します(コードがこれをクリアすることを願っています、テキストに入れるのは難しいです)

これが私の現在のコードです:

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型クラスです。つまりA、特定の方法で順序付けられたファクトをキャプチャする場合は、の暗黙的なインスタンスをスコープに入れるだけです。extend (またはなど)Ordering[A]はありません。AOrdering[A]Ordering[AnyVal]

このアプローチの利点は、特定のタイプに対して複数の順序を操作できることです(ただし、タイプに対して一度に1つの暗黙的な順序のみをスコープに含めることができます)。したがって、たとえば、次のように書くことができます。

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]]されたコンテキストを使用することで、これを簡単に修正できます。MMOrdering[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 に答える