Search code examples
scalainheritancecomparetype-parameter

Type mismatch, expected: T, actual: T


I'm not understanding what this error wants me to do:

Type mismatch, expected: T, actual: T

I only have 3 lines of code:

case class BaseElem[T](e: T)
case class OrderedElem[T <: Ordered](override val e: T) extends BaseElem[T](e) with Ordered[OrderedElem[T]] {
  override def compare(that: OrderedElem[T]): Int = this.e.compare(that.e)
}

BaseElem is a simple container of T's. OrderedElem is an Ordered container of T <: Ordered. So I want a comparison between OrderedElems to be the comparison of their respective elements.

The error is in the override of compare, the code highlighted by the error is that.e.

  1. What is this error saying and how do I fix it?

  2. Side question, can the declaration of OrderedElem be simplified and retain the desired semantics?


Solution

  • The issue was with the part OrderedElem[T <: Ordered]. After following om-nom-nom's smell cleanups and fixing the error he noted, I found that types like Int (with primitive representations) don't extent Ordered in Scala (see this question), so one must use a "view bound" <% to tell Scala to also look for available implicit conversions.

    Now I have:

    class BaseElem[T](val e: T)
    
    class OrderedElem[U <% Ordered[U]](override val e: U) extends BaseElem(e) with Ordered[OrderedElem[U]] {
      override def compare(that: OrderedElem[U]): Int = this.e.compare(that.e)
    }
    
    object Run extends App {
      val a = new OrderedElem(0)
      val b = new OrderedElem(1)
      println(a < b)  // => true
    }