Require a boxed generic value to provide a needed method.

upper-bound An upper bound such as `A <: HasSize` says that `A` must provide the members from `HasSize`. `SizedBox[A]` can read `size` from its item safely.

Bounded Type Parameter

text
BoundedSize.scala
Replay: real traced execution (multi-file project)
trait HasSize {
  def size: Int
}

case class Label(text: String) extends HasSize {
  def size: Int = text.length
  override def toString: String = "[label]"
}

case class SizedBox[A <: HasSize](item: A)

object Main {
  def main(args: Array[String]): Unit = {
    val text = "scala"
    val label = Label(text)
    val box = SizedBox[Label](label)
    val size = box.item.size
    val doubled = size * 2

    println("text=" + text)
    println("size=" + size)
    println("doubled=" + doubled)
  }
}
trait HasSize {
  def size: Int
}

case class Label(text: String) extends HasSize {
  def size: Int = text.length
  override def toString: String = "[label]"
}

case class SizedBox[A <: HasSize](item: A)

object Main {
  def main(args: Array[String]): Unit = {
    val text = "types"
    val label = Label(text)
    val box = SizedBox[Label](label)
    val size = box.item.size
    val doubled = size * 2

    println("text=" + text)
    println("size=" + size)
    println("doubled=" + doubled)
  }
}
trait HasSize {
  def size: Int
}

case class Label(text: String) extends HasSize {
  def size: Int = text.length
  override def toString: String = "[label]"
}

case class SizedBox[A <: HasSize](item: A)

object Main {
  def main(args: Array[String]): Unit = {
    val text = "generic"
    val label = Label(text)
    val box = SizedBox[Label](label)
    val size = box.item.size
    val doubled = size * 2

    println("text=" + text)
    println("size=" + size)
    println("doubled=" + doubled)
  }
}
  1. text ← scala, label ← [label], box ← SizedBox([label]), size ← 5

    12object Main {13  def main(args: Array[String]): Unit = {14    val text→ scala = "scala" //@text="types", "generic"15    val label→ [label] = Label(textscala)16    val box→ SizedBox([label]) = SizedBox[Label](label[label])17    val size→ 5 = box.item[label].size18    val doubled→ 10 = size5 * 21920    println("text=" + textscala)21    println("size=" + size5)22    println("doubled=" + doubled10)23  }24}
    outputtext=scala
    size=5
    doubled=10
  1. text ← types, label ← [label], box ← SizedBox([label]), size ← 5

    12object Main {13  def main(args: Array[String]): Unit = {14    val text→ types = "types"15    val label→ [label] = Label(texttypes)16    val box→ SizedBox([label]) = SizedBox[Label](label[label])17    val size→ 5 = box.item[label].size18    val doubled→ 10 = size5 * 21920    println("text=" + texttypes)21    println("size=" + size5)22    println("doubled=" + doubled10)23  }24}
    outputtext=types
    size=5
    doubled=10
  1. text ← generic, label ← [label], box ← SizedBox([label]), size ← 7

    12object Main {13  def main(args: Array[String]): Unit = {14    val text→ generic = "generic"15    val label→ [label] = Label(textgeneric)16    val box→ SizedBox([label]) = SizedBox[Label](label[label])17    val size→ 7 = box.item[label].size18    val doubled→ 14 = size7 * 21920    println("text=" + textgeneric)21    println("size=" + size7)22    println("doubled=" + doubled14)23  }24}
    outputtext=generic
    size=7
    doubled=14