6

バインドされた型パラメーターを持つクラス定義が与えられた場合、Scala コンパイラーはからAnimal[A <: String]推論しないようです。推論は許されますか?コンパイラが推論を行うのを助ける方法は?B <: StringAnimal[B]

以下は、この推論の欠如が問題となるケース クラスの具体的な例です。

次のケース クラス階層を考えてみましょう。

sealed trait Person[+T <: Person[T]]
case class Student() extends Person[Student]
case class Professor() extends Person[Professor]

たとえばUniversity、型の変数でインスタンス化できるケース クラスを定義する必要があります。これは次の定義で機能すると思いました。Person[_]val p: Person[_] = Student()

case class University(p: Person[_])

しかし、これはエラーでコンパイルに失敗します:

type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]]

ケースクラスの型パラメーターをバインドすると、Universityコンパイルされます(キーワードをドロップすると、無制限のパラメーターでもコンパイルされますcaseが、これは私の場合のオプションではありません):

case class BoundUniversity[P <: Person[P]](p: Person[P])

しかし、このパラメータ化されたバージョンは、タイプ の無制限の変数でインスタンス化することはできませんPerson[_]:

val p: Person[_] = Student()
BoundUniversity(p)

コンパイルに失敗します:

inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]]

次のようなバインドされた引数を持つメソッドでも同じエラーが発生します。

def general[P <: Person[P]](p: P) = println(p)

したがって、これはクラス コンストラクターに固有のものではありません。

2 つの質問:

  1. Personはパラメータ bounds で定義されるためPerson[+T <: Person[T]]、この型の各インスタンスはこれらの境界を尊重することが保証されます。または私は何かを逃していますか?では、コンパイラが文句を言わないようにするにはどうすればよいでしょうか?val p: Person[P]P <: Person[P]

  2. のようなバインドされていない型パラメーターを持つメンバーでケースクラスを定義する方法/できますcase class University(p: Person[_])か?

4

1 に答える 1

2

X[_]が欲しいものになることはめったにありません。型で使用する場合_、基本的には、そのパラメーターを使用する必要がないため、そのパラメーターが何であるかは気にしないと言っています。

とにかく、これはコンパイルされます。実存的なタイプはトリッキーなものですが...

case class University(p: Person[t] forSome { type t <: Person[t] })
于 2012-04-05T13:49:26.560 に答える