Union and Intersection Types in Scala 3

Photo by Denys Nevozhai on Unsplash

Scala 3 aka dotty comes with a lot of new types. Union, Intersection , Opaque etc. Let’s understand union and intersection types in detail.

Union types

This would not have been possible in Scala 2. We would have to create a super type for our types and then create the method with the super type.

Rules for Union types

  • A and B are sub types of A | B for all values of A and B
  • Co- Variance rules for Union types : Given a co-variant type C then C[A] | C[B] <: C[A | B]

Basically we can pass a List[Int] and a List[String] to a method expecting a List[Int|String]. This makes C[A] and C[B] a sub type of C[A|B].

Also we can pass List[String]|List[Int] type where a List[String|Int] is expected. This makes C[A] | C[B] a sub type of C[A|B]. However the reverse is not possible as seen in line 24.

  • Contra-variance rules for Union types : Given a contra variant type C then C[A | B] <: C[A] and C[A | B] <: C[B]

Here, we see that we could pass a Printer[String|Int] where a Printer[Int] was required.

Intersection types

At line 8 we are able to use both methods from intersection type i.e monoid contains the functionality of both Semigroup and Indentity types. The intersection type will also act as a type restriction, so we need to mix in both traits if we are to use this method properly.

Rules for Intersection types

  • Given any types A and B , A & B is a sub type for both A and B
  • Co- Variance rules for Intersection types : Given a co-variant type C then C[A & B] <: C[A] & C[B]

Here, we see that we can provide an Option[TwitterPost & InstagramPost]when we need a Option[TwitterPost] or a Option[InstagramPost]. This also leads us to the fact that when we need an Option[TwitterPost] & Option[InstagramPost] we can provide a Option[TwitterPost & InstagramPost] .

  • Given a contra-variant type C a C[A |B] is a sub type of C[A] & C[B]

What happens here is that a Printer instance which knows how to print Int|String can be passed when we need a Printer[Int] & Printer[String]. This is exactly what is done is line 15.

  • what happens the two intersected types share a method signature except the returned types?

Here both Singer and Dancer types have a method called share with the same signature but different return types. An intersection type of these two upon calling the share method must return both an InstagramPost and a TwitterPost. The only type that can do that is an intersection i.e TwitterPost & InstagramPost.