【问题标题】:Implementing trait PartialOrdered[T]实现特征 PartialOrdered[T]
【发布时间】:2013-05-04 23:29:42
【问题描述】:

作为练习,我应该实现一个特征 PartialOrdered[T]。

trait PartialOrdered[T] {
  def below(that: T): Boolean
  def < (that: T): Boolean = (this below that) && !(that below this)  

  /* followed by other relations <=, >, >=, ==, .. */
}

扩展此特征的类 K 应该在下面实现

a.below(b: K) = { true   if a <= b, 
                  false  in any other case

但是,编译会出现以下错误:

value below is not a member of type parameter T
def < (that: T): Boolean = (this below that) && !(that below this)
                                                        ^

那么我错过了什么?提前致谢

编辑:这是一个示例类 Rectangle(在坐标系中),给出了两个相对的角,如果一个矩形被完全包含在另一个矩形的下方

case class Rectangle (x1: Int, y1: Int, x2: Int, y2: Int) 
  extends PartialOrdered[Rectangle] {

  def below(r: Rectangle): Boolean = {
    val (rx, ry) = r.topLeft
    val (tx, ty) = this.topLeft
    tx >= rx && ty <= ry &&
    tx + this.width <= rx + r.width &&
    ty - this.height >= ry - r.height
  }

  def width: Int = {...}
  def height: Int = {...}
  def topLeft:(Int, Int) = {...}
}

【问题讨论】:

    标签: scala traits partial-ordering


    【解决方案1】:

    你必须告诉 Scala TPartialOrdered[T] 的子类型:

    trait PartialOrdered[T <: PartialOrdered[T]] { this: T =>
      def below(that: T): Boolean
      def < (that: T): Boolean = (this below that) && !(that below this)  
    
      /* followed by other relations <=, >, >=, ==, .. */
    }
    

    另见:scala self-type: value is not a member error

    【讨论】:

    • 这确实有效,但超出了我之前所学的。我尝试过类似的方法,但不适用于&lt;% 而不是&lt;: 还有this: T =&gt; 的目的是什么?
    【解决方案2】:

    这里需要两个概念。一种是F有界多态,一种是自类型约束。

    F-bounded polymorphism,没有深入到底层类型理论,本质上是使二元运算符工作的原因。您基本上定义了一个特征,使其参数成为其自身的子类型:

    trait PartialOrdered[T <: PartialOrdered[T]] {
      this: T =>
        def below(that: T): Boolean
        def <(that: T): Boolean =
          (this below that) && !(that below this)
    }
    

    要使this below thatthat below this 都可以工作,我们还需要约束自我类型。这是通过this: T =&gt; 完成的,因此编译器知道this 也是T 的一个实例,而不仅仅是PartialOrdered[T]

    然后你定义一个类来使用那个特性。它需要以自身作为类型参数来扩展 trait:

    case class Pair(x: Double, y: Double) extends PartialOrdered[Pair] {
      def below(that: Pair) =
        x <= that.x && y <= that.y
    }
    
    object Program extends App {
      println(Pair(1, 2) < Pair(2, 0))
      println(Pair(1, 2) < Pair(1, 3))
      println(Pair(1, 2) < Pair(0, 2))
      println(Pair(1, 2) < Pair(2, 2))
    }
    

    【讨论】:

      【解决方案3】:

      T 不一定是PartialOrdered[T] 的实例,因此它没有下面的方法。我想你的意思是

        def below(that: PartialOrdered[T]): Boolean
        def < (that: PartialOrdered[T]): Boolean = (this below that) && !(that below this)  
      

      ?

      【讨论】:

      • 我试过了,然后编译会要求在 Rectangle 类中正确实现below。但是只想比较矩形和矩形。
      • 然后查看 Debilski 的回答。
      猜你喜欢
      • 1970-01-01
      • 2017-12-05
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      • 2021-11-14
      相关资源
      最近更新 更多