Scala言語仕様(分散注釈に関するセクション4.5、p。44)は言う
- 型パラメーターの分散位置は、それを囲む型パラメーター句の分散位置の反対です。
- 型宣言または型パラメーターの下限の分散位置は、型宣言または型パラメーターの分散位置の反対です。
上記の最初のポイントを使用すると、(少なくとも形式的には) 簡単にわかります。
trait Covariant[+A] {
def problematic[B <: A](x : B)
}
エラーメッセージを生成します
error: covariant type A occurs in contravariant position in type >: Nothing <: A of type B
def problematic[B <: A](x : B)
1 番目と 2 番目のポイントを使用すると、簡単に確認できます。
trait Contravariant[-A] {
def problematic[B >: A](x : B)
}
エラーメッセージを生成します
error: contravariant type A occurs in covariant position in type >: A <: Any of type B
def problematic[B >: A](x : B)
前述したように、これらのエラーが発生する理由を形式的に (つまり、分散注釈の規則に従って) 確認するのは簡単です。ただし、これらの制限の必要性を示す例を思いつくことはできません。対照的に、メソッド パラメータが分散位置を変更する必要がある理由を説明する例を考え出すのは非常に簡単です。たとえば、分散注釈のチェックを参照してください。
そこで、私の質問は次のとおりです。上記の 2 つのコードが許可されたと仮定すると、発生する問題の例は何ですか? つまり、上記の 2 つのルールが使用されなかった場合に何が問題になるかを示す、これと同様の例を探しています。型の下限に関する例に特に興味があります。
Scala の型の境界と分散に対する回答では、この特定の質問が未解決のままであることに注意してください。一方、 「下限」で与えられた回答は、型の分散を逆にしますが、なぜでしょうか? 私には間違っているようです。
編集:最初のケースは次のように処理できると思います(上記の例を適応させます)。以下が許可されたとします。
trait Queue[+T] {
def head : T
def tail : Queue[T]
def enqueue[U <: T](x : U) : Queue[T]
}
次に、実装できます
class QueueImplementation[+T] extends Queue[T] {
/* ... implement Queue here ... */
}
class StrangeIntQueue extends QueueImplementation[Int] {
override def enqueue[U <: Int](x : U) : Queue[Int] = {
println(math.sqrt(x))
super.enqueue(x)
}
}
そしてそれを次のように使用します
val x : Queue[Any] = new StrangeIntQueue
x.enqueue("abc")
これは明らかに面倒です。ただし、「反変型パラメーター + 型下限」の組み合わせにも問題があることを示すために、これを適応させる方法がわかりませんか?