作为练习,我应该实现一个特性PartialOrdered[T]。
trait PartialOrdered[T] {
def below(that: T): Boolean
def < (that: T): Boolean = (this below that) && !(that below this)
/* followed by other relations <=, >, >=, ==, .. */
}
扩展这个trait的类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)
^
我错过了什么?提前感谢
编辑:这是一个矩形类的例子(在一个坐标系中),给出了两个相对的角,其中一个矩形低于另一个,如果它完全包含
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 T
是PartialOrdered[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不是成员错误
这里需要两个概念。一个是f有界多态性,另一个是自类型约束。
f -有界多态,不涉及潜在的类型理论,本质上是使二元操作符工作的原因。你基本上定义了一个trait,让它的参数是它自己的子类型:
trait PartialOrdered[T <: PartialOrdered[T]] {
this: T =>
def below(that: T): Boolean
def <(that: T): Boolean =
(this below that) && !(that below this)
}
为了使this below that
和that below this
都能工作,我们需要进一步约束自类型。这是通过this: T =>
完成的,这样编译器就知道this
也是T
的一个实例,而不仅仅是PartialOrdered[T]
。
然后定义一个类来使用该trait。它需要用自身作为类型参数来扩展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))
}
T
不一定是PartialOrdered[T]
的实例,所以它没有下面的方法。我想你是指
def below(that: PartialOrdered[T]): Boolean
def < (that: PartialOrdered[T]): Boolean = (this below that) && !(that below this)
?