generated at
variance
もともとは圏論の用語らしい


ある型 T と、それの部分型 S があり、
さらに、それらを型コンストラクタでwrapした型 C<T> C<S> がある時
T S の部分型関係は、 S <: T だが (ref 部分型 <: 上位型)
C<T> C<S> の部分型関係はどうなるのが型安全か?という話
C の種類によって、 C<S> <: C<T> となるべきだったり、 C<T> <: C<S> となるべきだったりする


4種類ある
S <: T ならば C<S> <: C<T>
S <: T ならば C<T> <: C<S>
covariantでもcontravariantでもないこと
S <: T ならば C<S> ≡ C<T>


以下のように捉えると直観に沿う
readする時は、covariantが必要
e.g. List<T>
writeする時は、contravariantが必要
e.g. 関数の引数
read/writeの両方を持ち合わせているものは、invariantである必要がある
e.g. Array<T>



参考
「変性」というまとまった章がある感じではない
15章で疎らに、共変や反変にふれる感じ




明示できる言語もある
Scala
+ でcovariant
- でcontravariant
何もなしだと、invariant
scala
trait Function1[-T, +U] { def apply(x: T): U }
Kotlin
out でcovariant
in でcontravariant
何もなしだと、invariant
TypeSciprt
out でcovariant
in でcontravariant
in out で、invariant



「共変」とか「反変」とかいう単語が何も想起しなくて分かりづらい
語源?を知りたい


>input/outputの話を図にしてるの初めて見たかも、いいですね
>
出典のスライドがわからない
たぶん@pd1xxさんの発表?