🎓 A1Learner
🔍
0 of 48 lessons completed

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?