Question

If I want to avoid the isInstanceOf & asInstanceOf combo, and instead want to use pattern matching, is there any simple way to avoid the erasure problem in the following example? I researched some answers but they all seem to use Manifest and the resulting code looked more complex than the undesirable isInstanceOf & asInstanceOf combo.

trait Comparable[A] extends Ordered[A] {
  override def equals(that : Any) = 
    that match {
      case that : A => compare(that) == 0
      case _ => false
    }
}

My goal in the code above is to create a single trait that adds implementation for == and != to the ordered comparators. However, I get the following error because A gets erased:

warning: abstract type pattern A is unchecked since it is eliminated by erasure
      case that : A => compare(that) == 0

NOTE: there are other similar questions on StackOverflow regarding this issue, but the accepted answers seem to use Manifest, hence my question - can this be achieved in a simpler way?

Was it helpful?

Solution

No, there is no simpler way. Manifest has been replaced by ClassTag and TypeTag, but there isn't any easy way to get the needed ClassTag - traits can't take parameters, and equals in Any wasn't declared to take an implicit ClassTag, so we have to force the implementing class to provide it:

import scala.reflect.ClassTag

trait Comparable[A] extends Ordered[A] {
  implicit def ct: ClassTag[A]

  override def equals(that: Any) = 
    that match {
      case that: A => compare(that) == 0
      case _ => false
    }
}

isInstanceOf won't help either, it will still require the ClassTag.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top