我有这个:
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() = ...
}
我想用
val l1 : List[Task] = tasks.sorted
val l2 : List[Subtask] = subtasks.sorted
但它不起作用:
error: diverging implicit expansion for type scala.math.Ordering[this.Subtask]
starting with method ordered in trait LowPriorityOrderingImplicits
,subtasks.sorted.map(_.render()).mkString(" | ")).mkString(" | ")
如何为各个构造函数编写具有不同排序的aglebraic类型?
答案 0 :(得分:2)
在Subtask
中,您没有正确覆盖父方法,因为它们采用不同的参数类型。试试这个:
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)
}
...
}
但是,在排序时,我们需要Ordering[Issue]
,而不是Ordering[Subtask]
,因为compare
方法需要Issue
。
因此,要对List[Subtype]
进行排序,以便编译器获取正确的Ordering
对象,需要将其键入为List[Issue]
而不是List[Subtask]
。
因此,在声明subtasks
时添加一个类型注释,或者在调用时添加一个类型注释:
(subtasks: List[Issue]).sorted
答案 1 :(得分:1)
您是否尝试将子类作为类型参数传递给抽象超类?像这样:
abstract class Issue[I <: Issue[I]](...) extends Ordered[I] {
def compare(o: I) = due.compare(o.due)
}
case class Task(...) extends Issue[Task](...)
case class Subtask(...) extends Issue[Subtask](...)