Scalaの型パラメータの変位指定
#scala #共変性と反変性
code:前提.scala
// 継承関係 = A <- B <- C
class A
class B extends A
class C extends B
// 型パラメータのある型
class KT
このとき、
code:代入可能性.scala
// Aの変数にBを代入することはできる。B is an A
scala> var x:A = new B
var x: A = B@51b90fe4
// しかし、KAにKBを代入することはできない。KB is _NOT_ a KA
scala> var x:KA = new KB
-- E007 Type Mismatch Error: --
なぜなら、AとBは継承関係にあるが、K[A]とK[B]は継承関係にないからである。
(デフォルトで非変)
ScalaではK[+T]と表記することで共変の指定ができる。
code:共変.scala
scala> class Kplus+T
// defined class Kplus
scala> var x:KplusA = new KplusB
var x: KplusA = Kplus@6770ebf4
すると、型パラメータの代入可能性が維持され、K[A]にK[B]が代入できるようになる。
K[-T]とすると代入可能性を逆にできる(反変)
code:反変.scala
scala> var x:KminusB = new KminusB
var x: KminusB = Kminus@1e1d64c4
scala> x = new KminusA
x: KminusB = Kminus@609cc30c
scala> x = new KminusC
-- E007 Type Mismatch Error: --
社内から↓
1. まず Top (型の最大元) が Any,Bottom (型の最小元) が Nothing であることを覚えます
(Any, Nothing は Scala の文脈。TypeScript であれば any, never で考えましょう)
2. つまり、任意の型 T に対して順序関係 Bottom ≦ T ≦ Top が成り立ちます
3. 型の代入可能性という意味では、X ≦ Y のとき、X は Y に対して代入ができます (順序の大きい方へ代入できる)
4. +T とは、この順序関係を維持する記法なので、代入可能性は通常通りです
5. 対して -T とは、この順序関係を反転する記法なので、代入可能性が逆転します
⇒ つまり、任意の型 T に対して順序関係を Top ≦ T ≦ Bottom と見なすということ
ゴミ箱のたとえ
https://sakataharumi.hatenablog.jp/entry/2020/09/16/014554