🎓 A1Learner
🔍
0 of 45 lessons completed

Intersection Types

An intersection type is a type that requires a value to satisfy two types at once. It is written with an ampersand between the type names.

One value can satisfy two traits

The entry provides a name and a count. The program prints the name and then the count.

trait Named:
  def name: String
trait Counted:
  def count: Int
class Entry(val name: String, val count: Int) extends Named, Counted
@main def main(): Unit =
  val e: Named & Counted = Entry("books", 3)
  println(e.name)
  println(e.count)

A function can use both traits

The function adds the name length to the count. The program prints that total.

trait Named:
  def name: String
trait Counted:
  def count: Int
class Entry(val name: String, val count: Int) extends Named, Counted
def score(x: Named & Counted): Int = x.name.length + x.count
@main def main(): Unit =
  val e: Named & Counted = Entry("books", 3)
  println(score(e))

An intersection value fits either trait alone

One function needs only a name. Another function needs only a count.

trait Named:
  def name: String
trait Counted:
  def count: Int
class Entry(val name: String, val count: Int) extends Named, Counted
def nameLength(x: Named): Int = x.name.length
def countOf(x: Counted): Int = x.count
@main def main(): Unit =
  val e: Named & Counted = Entry("books", 3)
  println(nameLength(e) + countOf(e))

Example

trait Named:
  def name: String
trait Counted:
  def count: Int
class Entry(val name: String, val count: Int) extends Named, Counted
def score(x: Named & Counted): Int = x.name.length + x.count
@main def main(): Unit =
  val first: Named & Counted = Entry("books", 3)
  val second: Named & Counted = Entry("pens", 2)
  println(score(first) + score(second))

Key points

  • Intersection type: An intersection type combines two traits into one requirement.
  • Trait: A trait is a reusable set of method names that a class can provide.
  • Value: A value of an intersection type provides the methods of both traits.
  • Function: A function can accept an intersection type when it needs both sets of methods.

In this example, the program builds two entries. It scores the first entry as 8 and the second as 6. It adds the scores to get 14.

Note

An intersection type differs from a union type because it requires both types, not just one of them.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

What must a value of type Named & Counted provide?