Magnolia Tech

いつもコードのことばかり考えている人のために。

Scala3学習メモ: Intersection型

Scalaではclassの定義時にtraitをmix-inできる。

scala> trait A
// defined trait A

scala> class B extends A
// defined class B

scala> val o1 = new B
val o1: B = B@36b53f08

この時、変数の型はBと推論されている。

また、オブジェクトの生成時にもmix-inできる。この時の型は先ほどと異なる結果となる。

scala> class C
// defined class C

scala> val o2 = new C with A
val o2: C & A = anon$1@5486ee92

この時の型はScala3から導入されたIntersection型により、変数はCとAを同時に持つ型として推論されている。

変数定義だけでなく、当然引数の型の宣言でも使える。

scala> def method(obj: A & C) = println(obj.toString)
def method(obj: A & C): Unit

scala> method(o2)
repl$.rs$line$6$$anon$1@5486ee92

Intersectionには型の継承関係が整理されているので、詳しくは公式ドキュメントを見ると良い。


Scala2の時は、Compound Typeという型で推論されていた。

scala> trait A
defined trait A

scala> class C
defined class C

scala> val o = new C with A
o: C with A = $anon$1@ecd379a

もちろん明示的に指定できる。

scala> val o2: C with A = new C with A
o2: C with A = $anon$1@22c7ef94

この変数の型におけるwithを使ったCompound Typeの記法は将来は廃止される予定であるとされている。

Scala3で明示的に指定してもIntersectionで置き換えられている。

scala> val o4: A with C = new C with A
val o4: A & C = anon$1@799971ac