Мне неясно, как добиться зависимых от пути типов в следующем фрагменте. Намерение состоит в том, чтобы иметь возможность использовать метод "объединения" для объединения двух куч. Для этого AFAIK требуются типы, зависящие от пути.
Вот это черта
trait Heap {
type H // type of a heap
type A // type of an element
def ord: Ordering[Heap#A] // ordering on elements
def meld(h1: Heap#H, h2: Heap#H): Heap#H // the heap resulting from merging h1 and h2
..
}
Вот часть реализации
class HeapImpl extends Heap {
override type H = HeapImpl // this.type
override type A = Integer
..
// the heap resulting from inserting x into h
override def meld(h1: Heap#H, h2: Heap#H): Heap#H = {
while (!isEmpty(h2)) {
insert(deleteMin(h2),h1)
}
this
}
Возвращаемое значение "this" в методе объединения вызывает ошибку компиляции:
Expression HeapImpl does not conform to expected type Heap#H
Ответ 1 · рейтинг 1 · Alexey Romanov
trait Heap {
type H <: Heap // type of a heap (added requirement that it must be a heap)
type A // type of an element
def ord: Ordering[A] // ordering on elements
def meld(h1: H, h2: H): H // the heap resulting from merging h1 and h2
..
}
Теперь, когда вы определяете
override def meld(h1: H, h2: H): H
в HeapImpl, H это просто HeapImpl и тип возвращаемого значения будет соответствовать.
Таким образом, A и H в методах совпадают с теми, которые определены в вашем type .... Типы, зависящие от пути, означают, что вы можете писать такие типы, как heap.A (где heap - это Heap).
Также отмечу, что ваша реализация meld выглядит странно. Похоже, вы вставляете элементы h2 в h1 (если нет, то что означает второй аргумент insert?), но затем вместо возврата h1 вы возвращаете this.
Ответ 2 · рейтинг 2 · som-snytt
Проекция Heap#H отличается от this.H.
scala> trait Heap { type H ; type A ; def m(h1: H, h2: H): H }
defined trait Heap
scala> class Impl extends Heap { type H = Impl; def m(h1: H, h2: H) = this }
defined class Impl