Type Members
A type member is a type declared inside a trait without a fixed meaning. Each implementation fixes the member to one concrete type.
An implementation fixes the member to Int
The Int box assigns Int to Item. The program prints its stored value.
trait Box:
type Item
val value: Item
class IntBox extends Box:
type Item = Int
val value = 42
@main def main(): Unit =
val box = IntBox()
println(box.value)Another implementation fixes the member to String
The String box assigns String to Item. The program prints the length of its stored value.
trait Box:
type Item
val value: Item
class StringBox extends Box:
type Item = String
val value = "hello"
@main def main(): Unit =
val box = StringBox()
println(box.value.length)A method can return the member type
The source defines a method that returns its member type. The program triples the returned value.
trait Source:
type Item
def get: Item
class IntSource extends Source:
type Item = Int
def get = 7
@main def main(): Unit =
val source = IntSource()
println(source.get * 3)Example
trait Box:
type Item
val value: Item
class IntBox extends Box:
type Item = Int
val value = 42
class StringBox extends Box:
type Item = String
val value = "hello"
@main def main(): Unit =
val intBox = IntBox()
val stringBox = StringBox()
println(intBox.value + stringBox.value.length)Key points
- Abstract type member: An abstract type member is a type name with no assigned type yet.
- Type parameter: A type parameter is a type name listed in brackets after a trait name.
- Refinement: An implementation refines a type member by assigning it a concrete type.
- Use: A type member lets one trait describe a container without fixing what it holds.
In this example, the program builds an Int box and a String box. It takes 42 from the Int box and 5 from the String box length. It adds them to get 47.
Note
A type member differs from a type parameter because it is named inside the trait, not in brackets after the name.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
How does an implementation fix an abstract type member?