The error is about incompatible type in overriding, not about implicits.
You should remove upper bound type T <: Ordered[T]
.
Int
doesn't extend Ordered
.
Try type parameter rather than type member
sealed abstract class Value[T] extends /*Expression with*/ Ordered[Value[T]] {
def value: T
override def compare(that: Value[T]): Int
}
case class IntValue(value: Int) extends Value[Int] {
override def compare(that: Value[Int]): Int = value.compare(that.value)
}
Similar code with type member
sealed abstract class Value extends /*Expression with*/ Ordered[Value {type T = self.T}] { self =>
type T
def value: T
override def compare(that: Value {type T = self.T}): Int
}
case class IntValue(value: Int) extends Value {
type T = Int
override def compare(that: Value {type T = Int}): Int = value.compare(that.value)
}
is not possible because of Error: illegal cyclic reference
.
Scala: Abstract types vs generics
https://typelevel.org/blog/2015/07/13/type-members-parameters.html
https://www.youtube.com/watch?v=R8GksuRw3VI
https://tpolecat.github.io/2015/04/29/f-bounds.html
If you want to delegate then you should use type class Ordering
rather than OOP trait Ordered
. Int
doesn't extend Ordered
but there is an instance of Ordering
for Int
sealed abstract class Value[T] {
def value: T
}
case class IntValue(value: Int) extends Value[Int]
implicit def valueOrdering[T, A](implicit
ev: A <:< Value[T],
ordering: Ordering[T]
): Ordering[A] = ordering.on(_.value)
import Ordering.Implicits._
IntValue(1) < IntValue(2) // -1
or
import Ordered._
IntValue(1) < IntValue(2) // true
IntValue(1).compare(IntValue(2)) // -1
Approach with type class can be used for type member
sealed abstract class Value {
type T
def value: T
}
case class IntValue(value: Int) extends Value {
override type T = Int
}
implicit def valueOrdering[A <: Value](implicit
ordering: Ordering[A#T]
): Ordering[A] = ordering.on(_.value)
// implicit def valueOrdering[_T, A](implicit
// ev: A <:< Value { type T = _T },
// ordering: Ordering[_T]
// ): Ordering[A] = ordering.on(_.value)