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?