I have this:
abstract class Issue( ... ) extends Ordered[Issue] {
def compare(o : Issue) = due.compare(o.due)
def render() : String
}
case class Task( ..., subtasks : scala.List[Subtask]) extends Issue( ... ) {
def render() = ...
}
case class Subtask( ..., parent : String ) extends Issue( ... ) {
override def compare(o:Subtask) = {
... delegate to some field's compare function ...
}
def render() = ...
}
I want to use
val l1 : List[Task] = tasks.sorted
val l2 : List[Subtask] = subtasks.sorted
But it does not work:
error: diverging implicit expansion for type scala.math.Ordering[this.Subtask]
starting with method ordered in trait LowPriorityOrderingImplicits
,subtasks.sorted.map(_.render()).mkString(" | ")).mkString(" | ")
How do I write this aglebraic type with different orderings for the individual constructors ?
In Subtask you're not overriding the parent method correctly, because they take different parameter types. Try this:
case class Subtask( ..., parent : String ) extends Issue( ... ) {
override def compare(o: Issue) = o match {
case x: Subtask => ... // your new comparison
case x => super.compare(x)
}
...
}
However, when sorting, we need an Ordering[Issue], not an Ordering[Subtask], because the compare method takes an Issue.
So to sort a List[Subtype], for the compiler to get the correct Ordering object, it needs to be typed as a List[Issue] rather than List[Subtask].
So add a type annotation where you declare subtasks, or upcast it thus when calling:
(subtasks: List[Issue]).sorted
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With