【问题标题】:Ordering with algebraic types in scala在scala中使用代数类型排序
【发布时间】:2012-08-10 21:22:17
【问题描述】:

我有这个:

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 类型?

【问题讨论】:

    标签: scala


    【解决方案1】:

    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
    

    【讨论】:

    • 你知道为什么编译器不搜索类型类实例的逆变类型吗?
    • @sschaef 不太清楚你的意思。 Ordering 是不变的;如果它是协变的,我们就不会有这个问题,但也许不是因为这里提到的问题:scala-lang.org/api/2.7.7/scala/Ordered.html
    • 是的,这就是我搜索的内容。
    【解决方案2】:

    您是否尝试过将子类作为类型参数传递给抽象超类?像这样的:

    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](...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-28
      • 2012-11-20
      • 2020-02-02
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      相关资源
      最近更新 更多