Note: This is a contrived example.
Consider the following existential type.
sealed trait Showable
final case class Show[A](show: A => String, value: A) extends Showable
I can define a show
method as follows:
def show(showable: Showable): String = showable match {
case Show(show, value) => show(value)
}
But the pattern match infers the type Any => String
and Any
for show
and value
respectively. Hence, I can also define a show
method as follows:
def show(showable: Showable): String = showable match {
case Show(show, value) => show(42)
}
This is unsafe. How do I ensure that within the case expression show
can only be applied to value
?
If you match a typed pattern then
def show(showable: Showable): String = showable match {
case s: Show[a] => s.show(s.value)
}
or
def show(showable: Showable): String = showable match {
case s: Show[_] => s.show(s.value)
}
compiles but
def show(showable: Showable): String = showable match {
case s: Show[a] => s.show(42)
}
//type mismatch;
// found : Int(42)
// required: a
or
def show(showable: Showable): String = showable match {
case s: Show[_] => s.show(42)
}
//type mismatch;
// found : Int(42)
// required: _
doesn't.