2013-05-04 3 views
1

В качестве упражнения я должен реализовать черту PartialOrdered [T].Реализующая черта 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) 
                 ^

Так что мне не хватает? Заранее спасибо

Edit: Это пример класса 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) = {...} 
} 

ответ

2

Вы должны сказать, что 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 is not a member error

+0

Это работает, но превышает то, что я узнал раньше. Я пробовал что-то подобное, которое не работало с '<%' вместо '<:' Также в чем цель 'this: T =>'? – marius

0

T не обязательно экземпляр PartialOrdered[T], поэтому он не имеет метода ниже. Я думаю, вы имели в виду

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

?

+0

Я попробовал это, компилятор запросит правильную реализацию 'ниже' в классе Rectangle. Однако только хотите сравнить Rectangles с Rectangles. – marius

+0

Тогда ответ Дебильского. – Cubic

1

Вам понадобятся два понятия здесь. Один из них - F-ограниченный полиморфизм, другой - ограничения типа типа.

F-ограниченный полиморфизм, не вдаваясь в теорию базового типа, по существу делает работу двоичных операторов. Вы в основном определить черту, чтобы ее параметр быть подтипом себя:

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

Затем вы определяете класс для использования этой черты. Он должен расширить признак с самим собой как параметр типа:

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)) 
}