5

私は現在、scala の分散を研究しており、反分散については十分に理解していると思います。たとえば、が のスーパータイプであるtrait List[-A]ことはわかっています。List[Int]List[AnyVal]

しかし、私には次の特徴があるとしましょう。

trait List[+A] {
  def cons(hd: A): List[A]
}

consパラメータの型が間違っているのはなぜですか?

なぜそれが必要なのdef cons[B >: A](v: B): List[B]ですか?

例えば:

val animal_list: List[Animal] = List(tiger, dog)

呼び出す場合:

animal_list.cons(tiger)

以来、問題に遭遇してTiger <: Animalいませんか?consBありTigerAありAnimal、ありませんのでB >: A、真ではありません。

4

1 に答える 1

6

consのパラメータ タイプが間違っているのはなぜですか?

trait List[+A] {
  def cons(hd: A): List[A]
}

コンパイラはエラーを出します:
covariant type A occurs in contravariant position in type A of value hd
メソッドパラメータは反変の位置としてカウントされますが、A共変であるためです。

このメソッド宣言がコンパイルされると想像してみましょう。次に、次のことができます。

class ListImpl[A] extends List[A] {
  override def cons(hd: A): List[A] = ???
}

val strings: List[String] = new ListImpl[String]
val values: List[Any] = strings // OK, since List[String] <: List[Any] (in List[A], A is covariant)
values.cons(13) // OK(??), since values's static type is List[Any], so argument of cons should be Any, and 13 conforms to type Any

上記の最後の行は本当に OK ですか? を呼び出しconsていvaluesます。valuesと同じでstringsstrings型のオブジェクトですListImpl[String]。したがってcons、最後の行の呼び出しは引数を期待していますが、の静的型はであり、 に準拠しているため、Stringを渡しています。ここで何かが間違いなく間違っています - どの行が原因ですか? 答えは、メソッド宣言です。この問題を解決するには、共変の型パラメーターを反変の位置 (宣言内) から削除する必要があります。あるいは、非共変にすることもできます。IntvaluesList[Any]IntAnyconsAconsA

次の質問も参照してください: #1#2

cons...問題に遭遇していませんか?

trait List[+A] {
  def cons[B >: A](v: B): List[B]
}

val animal_list: List[Animal] = List(tiger, dog)  // We are assuming that List.apply and concrete implementation of List is somewhere defined.

いいえ、animal_list.cons(tiger)呼び出しは正しいタイプです。

Animalは andの共通のスーパータイプでDogありTiger、 andはそれぞれdogandtigerのインスタンスであると仮定します。DogTiger

animal_list.cons(tiger)呼び出しでは、 と タイプ パラメータの両方がABインスタンス化されるAnimalため、consメソッドは次の形式になります。

def cons[Animal >: Animal](v: Animal): List[Animal]

Animal >: Animal制約は次の理由で満たされます。

スーパータイプとサブタイプの関係は再帰的です。つまり、タイプはそれ自体のスーパータイプであると同時にサブタイプでもあります。[ソース]

への引数consTigertype に準拠してAnimalいるため、メソッド呼び出しは正しい型です。

のようBにインスタンス化を強制すると、この呼び出しは型が正しくなくなり、コンパイラ エラーが発生することに注意してください。Tigeranimal_list.cons[Tiger](tiger)

ここで同様の例を参照してください。

于 2016-05-20T00:41:37.250 に答える