3

我有这个:

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(" | ")

如何为各个构造函数编写具有不同排序的这种 agebraic 类型?

4

2 回答 2

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

因此,要对 a 进行排序List[Subtype],编译器要获得正确的Ordering对象,需要将其键入为 aList[Issue]而不是List[Subtask]

所以在你声明的地方添加一个类型注释subtasks,或者在调用时向上转换它:

(subtasks: List[Issue]).sorted
于 2012-08-10T12:39:25.800 回答
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](...)
于 2012-08-10T09:20:32.703 回答