6

(私はScalaナイトリーを使用しており、2.8.0b1 RC4でも同じ動作が見られます。私はScalaの新参者です。)

SortedMap結合したいものが2つあります。使用したいコードは次のとおりです。

import scala.collection._

object ViewBoundExample {
    class X
    def combine[Y](a: SortedMap[X, Y], b: SortedMap[X, Y]): SortedMap[X, Y] = {
        a ++ b
    }
    implicit def orderedX(x: X): Ordered[X] = new Ordered[X] { def compare(that: X) = 0 }
}

ここでの考え方は、「暗黙の」ステートメントは、Xsをsに変換できることを意味し、マップだけでなく、sを別のにOrdered[X]結合することは理にかなっています。SortedMapSortedMap

コンパイルすると、

sieversii:scala-2.8.0.Beta1-RC4 scott$ bin/scalac -versionScala compiler version
2.8.0.Beta1-RC4 -- Copyright 2002-2010, LAMP/EPFL

sieversii:scala-2.8.0.Beta1-RC4 scott$ bin/scalac ViewBoundExample.scala
ViewBoundExample.scala:8: error: type arguments [ViewBoundExample.X] do not
    conform to method ordered's type parameter bounds [A <: scala.math.Ordered[A]]
        a ++ b
          ^
one error found

その型パラメータのバインドが。[A <% scala.math.Ordered[A]]ではなく、である場合、私の問題はなくなるよう[A <: scala.math.Ordered[A]]です。残念ながら、「注文した」メソッドがどこにあるのかさえわかりません。誰かが私がそれを追跡するのを手伝ってもらえますか?

それができない場合、2つのsの和集合を生成するために私は何をするつもりSortedMapですか?コンバインのリターンタイプを削除する(またはに変更するMap)と、すべてが正常に機能します---しかし、リターンがソートされていることに依存することはできません!

4

2 に答える 2

5

現在使用しているのはscala.collection.SortedMapトレイトであり、その++メソッドはトレイトから継承されMapLikeます。したがって、次の動作が表示されます。

scala> import scala.collection.SortedMap
import scala.collection.SortedMap

scala> val a = SortedMap(1->2, 3->4)
a: scala.collection.SortedMap[Int,Int] = Map(1 -> 2, 3 -> 4)

scala> val b = SortedMap(2->3, 4->5)
b: scala.collection.SortedMap[Int,Int] = Map(2 -> 3, 4 -> 5)

scala> a ++ b
res0: scala.collection.Map[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)

scala> b ++ a
res1: scala.collection.Map[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)

の戻り結果の型はです。これ++は、返すオブジェクトのメソッドにMap[Int, Int]意味がある唯一の型であるためです。のsortedプロパティを保持しているようです。これは、抽象メソッドを使用して連結を実行し、それらの抽象メソッドがマップの順序を保持するように定義されているためだと思います。++MapLike++SortedMap++

2つのソートされたマップを結合するには、を使用することをお勧めしますscala.collection.immutable.SortedMap

scala> import scala.collection.immutable.SortedMap
import scala.collection.immutable.SortedMap

scala> val a = SortedMap(1->2, 3->4)
a: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 2, 3 -> 4)

scala> val b = SortedMap(2->3, 4->5)
b: scala.collection.immutable.SortedMap[Int,Int] = Map(2 -> 3, 4 -> 5)

scala> a ++ b
res2: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)

scala> b ++ a
res3: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)

このSortedMapトレイトの実装は、++を返すメソッドを宣言しますSortedMap

次に、型の境界に関する質問に対するいくつかの回答を示します。

  • Ordered[T]<は、クラスに混在している場合に、、、、、、を使用し>てそのクラスを比較できることを指定する特性=です。、 for 、forを返す抽象メソッドを定義するだけです。次に、他のすべてのメソッドは、の結果に基づいてトレイトに実装されます。>=<=compare(that: T)-1this < that1this > that0this == thatcompare

  • T <% UScalaでバインドされたビューを表します。これは、タイプTがのサブタイプであるか、スコープ内の暗黙的な変換によってU暗黙的に変換できることを意味します。コードは、のサブタイプではないが、暗黙の変換を使用して暗黙的に変換できるので、入れないU場合に機能します。<%<:XOrdered[X]Ordered[X]OrderedX

編集:あなたのコメントについて。を使用している場合scala.collection.immutable.SortedMapでも、不変SortedMapはとして定義されているため、実装ではなくインターフェイスにプログラミングしていますtrait。これは、のより特殊な特性と見なすことができますscala.collection.SortedMap。これは、追加の操作(++を返すSortedMapなど)と不変であるというプロパティを提供します。これはScalaの哲学(不変性を好む)と一致しているため、不変を使用しても問題はありませんSortedMap。この場合、結果が確実にソートされるという事実を保証できます。コレクションは不変であるため、これを変更することはできません。

しかし、私はまだ、魔女が結果としてaを返すメソッドscala.collection.SortedMapを提供しないのは奇妙だと思います。私が行ったすべての限定されたテストは、2つのsの連結の結果が、ソートされたプロパティを保持するマップを実際に生成することを示唆しているようです。++SortedMapscala.collection.SortedMap

于 2009-12-21T12:59:56.460 に答える
4

Scalaの初心者として、ひびを入れるのに難しいナッツを選んだことがありますか?:-)

わかりました、簡単なツアーです。今は完全に理解することを期待しないでください。まず、問題はメソッドで発生することに注意してください++。その定義を検索すると、特性でそれが見つかり、またはのMapLikeいずれかを受け取ります。は、であるため、使用されているバージョンです。IteratorTraversableySortedMapTraversable

その広範な型シグネチャで、CanBuildFrom渡されていることに注意してください。暗黙的に渡されるため、通常は心配する必要はありません。しかし、何が起こっているのかを理解するために、今回はそうします。

CanBuildFromは、の定義に表示されている場所をクリックする++か、フィルタリングすることで見つけることができます。ランドールがコメントで述べたように、scaladocページの左上にマークされていない空白のフィールドがあります。そこをクリックして入力するだけで、入力した内容に一致するものが返されます。

したがって、CanBuildFromScalaDocで特性を調べて、それを選択します。多数のサブクラスがあり、それぞれが特定のタイプのコレクションの構築を担当します。サブクラスを検索してクリックしますSortedMapCanBuildFromSortedMapこれは、からを生成するために必要なオブジェクトのクラスですTraversable。インスタンスコンストラクター(クラスのコンストラクター)については、暗黙のOrderingパラメーターを受け取ることに注意してください。今、私たちは近づいています。

今回は、フィルターフィルターを使用してを検索しOrderingます。そのコンパニオンオブジェクト(名前の小さな「o」をクリック)は、Orderingsを生成する暗黙のオブジェクトをホストします。これは、コンパニオンオブジェクトが、そのクラスのインスタンスまたは変換を生成する暗黙のオブジェクトについて検査されるためです。LowPriorityOrderingImplicitsこれは、オブジェクトが拡張するトレイト内で定義され、Orderingそれを見ると、必要な...ordered[A <: Ordered[A]]を生成するメソッド、Orderingまたは問題がなければ生成するメソッドが表示されます。

これをもっと注意深く調べる前に私が持っていたように、からXへの暗黙の変換で十分だと思うかもしれません。Ordered[X]ただし、これはオブジェクトの変換であり、のサブタイプであるタイプを受け取るorderedことを期待しています。型のオブジェクトを型のオブジェクトに変換することはできますが、それ自体はのサブタイプではないため、パラメータとしてに渡すことはできません。Ordered[X]XOrdered[X]XOrdered[X]ordered

一方、のval Ordering[X]代わりに暗黙のを作成することdef Ordered[X]で、問題を回避できます。具体的には:

object ViewBoundExample {
    class X
    def combine[Y](a: SortedMap[X, Y], b: SortedMap[X, Y]): SortedMap[X, Y] = {
        a ++ b
    }
    implicit val orderingX = new Ordering[X] { def compare(x: X, y: X) = 0 }
}

私はほとんどの人がOrdered/に対する最初の反応Orderingは困惑の1つでなければならないと思います:なぜ同じことのためのクラスがあるのですか?前者はを拡張java.lang.Comparableし、後者はを拡張しjava.util.Comparatorます。残念ながら、の型compareアノテーションは主な違いをほぼ要約しています。

def compare(that: A): Int     // Ordered
def compare(x: T, y: T): Int  // Ordering

の使用には、の定義を変更できるようにする必要があるを拡張するOrdered[A]か、をに変換できるメソッドを渡す必要があります。Scalaは後者を簡単に実行できます、比較する前に各インスタンスを変換する必要があります。AOrdered[A] AAOrdered[A]

一方、を使用するにOrdering[A]は、上記のように単一のオブジェクトを作成する必要があります。これを使用するときは、タイプの2つのオブジェクトを渡すだけですAcompareプロセスでオブジェクトは作成されません。

Orderingそのため、パフォーマンスが向上する可能性がありますが、Scalaがoverを好む理由ははるかに重要Orderedです。コンパニオンオブジェクトをもう一度見てくださいOrdering。そこに定義されているScalaクラスの多くにはいくつかの暗黙的なものがあることに気付くでしょう。Tのコンパニオンオブジェクト内で暗黙のforクラスが検索されることを前述したことを思い出してくださいT。これが、まさに起こっていることです。

これも同様に行うことができます。Orderedただし、これが問題です。つまり、両方OrderingをサポートするすべてのメソッドOrderedが失敗します。これは、Scalaがそれを機能させるために暗黙的なものを探し、2つを見つけるためです。1つは、、Orderingもう1つはOrdered。どちらが必要かを判断できないため、Scalaはエラーメッセージを表示します。それで、選択がなされなければならなかった、そしてOrderingそれのためにもっと進んでいました。

ordered[A <% Ordered[A]]ええと、署名が。ではなく、として定義されていない理由を説明するのを忘れましたordered[A <: Ordered[A]]。そうすることで、前述の二重暗黙の失敗が発生するのではないかと思いますが、実際にこのようなことを行い、二重暗黙の問題を抱えていた人に、この特定の方法に問題があるかどうかを尋ねます。

于 2009-12-21T12:28:14.560 に答える