2014-02-26 2 views
0

Непонятно, как достичь зависимых от пути типов в следующем фрагменте. Цель состоит в том, чтобы иметь возможность использовать метод «meld» для слияния двух куч. Для AFAIK требуются типы, зависящие от пути.Noob to scala зависимые от типа типы

Вот черта

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 
    } 

Возвращаемое значение "это" по методу оплавления страдает ошибку компиляции:

Expression HeapImpl does not conform to expected type Heap#H 

ответ

1
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

Проекция Куча # 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