4

Scala で適切に入力するのに問題があります。クラス階層に Ordered を課して、このようなことをしたいのですが、サブクラスを使用して、比較メソッドが独自の型のパラメーターでのみ機能するようにします。

abstract class Parent extends Ordered
class A extends Parent {
  override def compare(that : A) = 1
}
class B extends Parent {
  override def compare(that : B) = 1
}

以下は機能しますが、その場合、親とそのサブクラスに型の特異性を永遠に課すことを余儀なくされます。これは、正しく推論するための悪夢になります。

abstract class Parent[T <: Parent[_]] extends Ordered[T]
class A extends Parent[A] {
  override def compare(that : A) = 1
}
class B extends Parent[A] {
  override def compare(that : B) = 1
}

Ordered[T] のサブクラスで型を強制する簡単な方法はありますか?

4

4 に答える 4

2

なぜだけではないのですか

abstract class Parent
class A extends Parent with Ordered[A] {...}
class B extends Parent with Ordered[B] {...}

他の人が指摘しているように、あなたの比較基準によれば、Parentそのサブクラスは比較できないため、sのシーケンスは順序付けられません。そのサブクラスのみがOrderedであるため、そこにトレイトを実装します。

于 2012-06-02T21:57:55.110 に答える
1

ルイージ、それが正しい答えだと思います。Java OO パラダイムからこれに取り組んでいると思います。そこでは、基になる型を知らずに親のグループを注文する必要があるのが一般的です。少なくとも私の小さな設定では、機能的なアプローチを正しく設定すれば、コレクションのタイプを知ることができることに気づき始めています。

于 2012-06-03T10:49:47.063 に答える
1

この問題が少し厄介なのは同意しますが、探している動作が許可されているとしたら、少し奇妙です。あなたがしたと仮定すると

trait Parent {
    this: Ordered[ThisType]
}

// Does A need to be Ordered[A]?
trait A extends Parent

// Should B, C be comparable? If A is Ordered, then they
// have to be. But is this what you want?
class B extends A
class C extends A

// Now what?
class D extends B

基本的に、継承を使用してこのようなプロパティを強制するのは少し奇妙です...おそらく理論的には機能させることができますが、継承の意図から逸脱することになります. Ordered代わりに、必要に応じてメソッドで制約を指定できます。

def foo[T <: Ordered[T]](x: T) = ...

または、制約と可能な他のものを共通の名前でグループ化したい場合はOrdered、型クラス スタイルの特性を作成できます。

trait Parent[A] {
    val order: Ordering[A]
}

def foo[T : Parent](x: T, y: T) {
    println(implicitly[Parent[T]].order.compare(x, y))
}

このソリューションの残念な点は、指定できないことsealedです。誰かがそれを回避する方法を持っているなら、私は興味があります。それ以外の場合は、依存して型付けされたプログラミング言語を使用できます。この種のことは少し得意です。

于 2012-06-02T16:26:04.357 に答える
0

とても良い洞察です。ありがとうございます。解決策としてこれに火をつけただけですが、率直に言って、少し臭いようで、少し緊張します. コメント?

abstract class Parent extends Ordered[Parent] {
  override def compare(that : Parent) : Int = {
    (this, that) match {
      case (x : A, y : A) =>  x.compare(y)
      case (x : B, y : B) =>  x.compare(y)
      case _ =>  throw new ClassCastException
    }
  }
}
class A extends Parent {
  def compare(that : A) = 1
}
class B extends Parent {
  def compare(that : B) = 1
}
于 2012-06-02T16:51:26.767 に答える