I don't really get this little thingy. I have an abstract class Box with several sub-classes for different types. For example
abstract class Box
class StringBox(val sValue : String) extends Box
The apply method in the companion object for Box is simple:
object Box{
def apply(s: String) = new StringBox(s)
def apply(b: Boolean) = new BooleanBox(b)
def apply(d: Double) = new DoubleBox(d)
}
so I can write
val sb = Box("StringBox)
Okay, writing unapply makes some trouble. My first idea was to use pattern matching on the type, like this this:
def unapply(b: Box) = b match {
case sb: StringBox => Some(sb.sValue)
case bb: BooleanBox => Some(bb.bValue)
case db: DoubleBox => Some(db.dValue)
case _ => None
}
Which simply doesn't work because of type erasures.
Second attempt was a generic Box[T] with type T and an abstract type member re-defined in each sub classes. For instance:
abstract class Box[T] {def value : T}
class StringBox(val sValue : String) extends Box[String] {
override def value : String = sValue
}
Consequently, I can re write my unapply as:
def unapply[T](b: Box[T]) = b match {
case sb: Box[String] => Some(sb.value)
case bb: Box[Boolean] => Some(bb.value)
case db: Box[Double] => Some(db.value)
case _ => None
Unfortunately, this doesn't work either. So I guess the explicit type reference in Box[String] gets erased as well so I need to use a type manifest instead. Maybe something like:
def unapply[T](b: Box[_])(implicit target: Manifest[T]): Option[T] = {
if(b.value == target) Some(b.value.asInstanceOf[T])
else None
}
This code compiles (2.10) but still does not the desired implicit conversion. Why?
Simple question, is there a way to do value extraction without using reflection or a manifest?
What really boggles me is the question if there is a simple(r) way to combine polymorphism and pattern matching? If not, are there other ways in Scala to accomplish a similar effect?
Any idea or suggestions?
Thank you very much.