Scala Context Bounds
A context bound is a short way to ask for a given instance in a type parameter list. Writing T: Show asks the compiler for a given Show[T].
A context bound asks for a given instance
Display takes a type with a Show bound. Summon fetches the given Show for Int.
trait Show[T]:
def show(v: T): String
given Show[Int] with
def show(v: Int): String = v.toString
def display[T: Show](v: T): String = summon[Show[T]].show(v)
@main def main(): Unit =
println(display(42))A context bound works over a whole list
ShowAll takes a list of any type with a Show bound. Each item is shown and the results are joined.
trait Show[T]:
def show(v: T): String
given Show[Int] with
def show(v: Int): String = v.toString
def showAll[T: Show](xs: List[T]): String =
xs.map(v => summon[Show[T]].show(v)).mkString(", ")
@main def main(): Unit =
println(showAll(List(4, 5, 6)))A context bound matches the using form
One method uses a using parameter and the other uses a context bound. Both print the same result.
trait Show[T]:
def show(v: T): String
given Show[Int] with
def show(v: Int): String = v.toString
def displayUsing[T](v: T)(using s: Show[T]): String = s.show(v)
def displayBound[T: Show](v: T): String = summon[Show[T]].show(v)
@main def main(): Unit =
println(displayUsing(42))
println(displayBound(42))Example
trait Show[T]:
def show(v: T): String
given Show[String] with
def show(v: String): String = "\"" + v + "\""
def display[T: Show](v: T): String = summon[Show[T]].show(v)
def showAll[T: Show](xs: List[T]): String =
xs.map(v => summon[Show[T]].show(v)).mkString(", ")
@main def main(): Unit =
println(display("hi"))
println(showAll(List("a", "b")))Key points
- Context bound: a requirement written after a type parameter, such as T: Show.
- Requirement: T: Show means a given Show[T] must be in scope at the call.
- Summon: summon[Show[T]] fetches the required instance inside the method.
- Shorthand: a context bound is a shorter way to write a using parameter for the same trait.
- Call site: the caller still passes only the value. The compiler supplies the instance.
In this example, the given Show for String wraps a value in quotes. Display shows one word with a context bound. ShowAll shows a list of words with the same bound, so the two lines print the quoted word hi and the quoted words a and b joined with a comma.
Note
a context bound hides the instance name, so the method reaches it with summon.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Scastie
Exercise
What does def display[T: Show](v: T) require at the call?