0

を含むデータ構造を作成しようとしてPriorityQueueいます。私はそれの非一般的なバージョンを作ることに成功しました。私が抱えている AI の問題を解決してくれるので、うまく機能していると言えます。
ここにそのスニペットがあります:

class ProntoPriorityQueue { //TODO make generic

implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] {
   def compare(other: Node) = node.compare(other)
}

val hashSet = new HashSet[Node]
val priorityQueue = new PriorityQueue[Node]()
...

私はそれを汎用にしようとしていますが、このバージョンを使用すると問題の解決が停止します:

class PQ[T <% Ordered[T]] {
//[T]()(implicit val ord: T => Ordered[T]) {
//[T]()(implicit val ord: Ordering[T] {

val hashSet = new HashSet[T]
val priorityQueue = new PriorityQueue[T]
...

使用する代わりにコメントアウトされたものも試しました[T <% Ordered[T]]

を呼び出すコードは次のPQとおりです。

//the following def is commented out while using ProntoPriorityQueue
implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] {
     def compare(other: Node) = node.compare(other)
} //I've also tried making this return an Ordering[Node]

val frontier = new PQ[Node] //new ProntoPriorityQueue
//have also tried (not together): 
val frontier = new PQ[Node]()(orderedNode)

また、暗黙の定義をNodeオブジェクトに移動(およびインポート)しようとしましたが、本質的に同じ問題です。

ジェネリックバージョンで何が間違っていますか? 暗黙的なものはどこに置くべきですか?


解決策 問題は私の暗黙の定義にありませんでした。問題は、ステートメントSetで自動的に生成された によって暗黙的な順序付けが選択されていたことです。for(...) yield(...)これにより、生成されたセットに 1 つの状態しか含まれないという問題が発生しました。

4

2 に答える 2

1

()でを定義し、すでに一般的なScalaを使用することの何が問題になっていOrderingますか?NodeOrdering[Node]PriorityQueue

原則として、またはOrdering[T]よりも使用することをお勧めします。概念的には、型自体の固有の(継承または実装された)プロパティです。特に、タイプは、この方法で定義された固有の順序関係を1つだけ持つことができます。順序関係の外部仕様です。はいくつでも存在する可能性があります。T <: Ordered[T]T <% Ordered[T]Ordered[T]Ordering[T]Ordering[T]

また、まだ気付いていない場合は、との違いはT <: UT <% U前者には名目上のサブタイプ関係(実際の継承)のみが含まれるのに対し、後者にはタイプに準拠する値を生成する暗黙的な変換の適用も含まれることを知っておく必要がありますバウンド。

したがって、使用する必要があり、クラスにメソッドが定義されNode <% Ordered[Node]ていない場合は、比較が必要になるたびcompareに暗黙的な変換が適用されます。さらに、タイプ独自のが含まれている場合、暗黙の変換が適用されることはなく、その「組み込み」の順序に固執します。compare

補遺

クラスに基づいたいくつかの例を示します。これCIStringを単にカプセル化し、Stringケース不変として順序付けを実装するものと呼びます。

/* Here's how it would be with direct implementation of `Ordered` */

class   CIString1(val s: String)
extends Ordered[CIString1]
{
  private val lowerS = s.toLowerCase

  def compare(other: CIString1) = lowerS.compareTo(other.lowerS)
}

/* An uninteresting, empty ordered set of CIString1
    (fails without the `extends` clause) */
val os1 = TreeSet[CIString1]()


/* Here's how it would look with ordering external to `CIString2`
    using an implicit conversion to `Ordered` */

class CIString2(val s: String) {
  val lowerS = s.toLowerCase
}

class CIString2O(ciS: CIString2)
extends Ordered[CIString2]
{
  def compare(other: CIString2) = ciS.lowerS.compareTo(other.lowerS)
}

implicit def cis2ciso(ciS: CIString2) = new CIString2O(ciS)

/* An uninteresting, empty ordered set of CIString2
    (fails without the implicit conversion) */
val os2 = TreeSet[CIString2]()


/* Here's how it would look with ordering external to `CIString3`
    using an `Ordering` */

class CIString3(val s: String) {
  val lowerS = s.toLowerCase
}

/* The implicit object could be replaced by
    a class and an implicit val of that class */
implicit
object  CIString3Ordering
extends Ordering[CIString3]
{
  def compare(a: CIString3, b: CIString3): Int = a.lowerS.compareTo(b.lowerS)
}

/* An uninteresting, empty ordered set of CIString3
    (fails without the implicit object) */
val os3 = TreeSet[CIString3]()
于 2013-02-13T04:23:44.757 に答える
0

考えられる問題の 1 つは、あなたが:Ordered[Node] ではないことです。Node

implicit def orderedNode(node: Node): Ordered[Node] = new Ordered[Node] {
  def compare(other: Node) = node.compare(other)
}

代わりに、あなたが試しOrdering[Node]たと言いますが、それ以上の情報はありません。PQとして宣言されPQ[T : Ordering]ます。

于 2013-02-13T05:58:01.093 に答える