Scala абстрактен път зависим тип проблем

Някой знае ли какво става тук с тази грешка на компилатора? Грешката изчезва, ако не разширя INode.

trait AbsTypes
{
    type TKey
    type TValue
}

trait INode extends AbsTypes
{
    def get(key : TKey) : TValue
    def set(key : TKey, v : TValue) : INode
}

class ANode[TKey,TValue](
  val akey : TKey,
  val aval : TValue
) extends INode
{
    // ERROR : type mismatch;  found   : ANode.this.aval.type (with underlying type TValue)  required: ANode.this.TValue
    def get(key : TKey) : TValue = { aval }
    def set(key : TKey, v : TValue) : INode = {
        new ANode(key,v)
    }
}

person ACyclic    schedule 25.07.2010    source източник


Отговори (2)


Общите параметри не заменят автоматично абстрактните типове, дори ако имат еднакви имена. Опитайте да преименувате общите параметри (за да избегнете конфликти с имена) и след това да декларирате типовете TKey и TValue в тялото на метода.

class ANode[A,B](
  val akey : A,
  val aval : B
) extends INode {
    type TKey=A
    type TValue=B
    def get(key : TKey) : TValue =  aval 
    def set(key : TKey, v : TValue) : INode = new ANode(key,v)
}

Предполагам, че би било хубаво, ако компилаторът издаде грешка на реда, където сте посочили имената на генеричните типове, вместо да чакате, докато започнете да използвате тези типове.

person Ken Bloom    schedule 26.07.2010
comment
Благодаря, това разреши тази част, но имам последващ въпрос, който ще публикувам отделно - person ACyclic; 26.07.2010
comment
Може да си струва да добавите тук stackoverflow.com/questions/1332574/ - person oluies; 26.07.2010

За съжаление нямам време да тествам това, което ще напиша, но моето разбиране за вашия код е, че всеки INode ще получи свой собствен тип TValue. Така че операцията get наистина връща INode.this.TValue, който не е съвместим с друг тип TValue на друг възел.

Начинът да избегнете това може да бъде да напишете:

trait Nodes {
  type TKey
  type TValue

  trait INode {
   def get(key : TKey) : TValue
  }

  class ANode(
    val akey : TKey,
    val aval : TValue
  ) extends INode
}
person Eric    schedule 26.07.2010
comment
Той все още ще има същия проблем с вашия код, защото akey и aval са от типовете, посочени от генеричните, а не от абстрактните типове. (Освен това, ако компилирате само този код, няма да забележите никакви грешки на компилатора, защото не сте се опитали да използвате конфликтните типове.) - person Ken Bloom; 26.07.2010
comment
О, да, това е грешка при копиране и поставяне. Намерението ми беше да използвам типовете от чертата Nodes. - person Eric; 26.07.2010
comment
Редактирах отговора ви, за да отразя това намерение, и премахнах моя вот против. - person Ken Bloom; 26.07.2010
comment
Благодаря, това ще свърши работа, но добавя нежелана препратка към външния тип в моя екземпляр на възел. Опитвам се да направя възела възможно най-малък/ефективен - person ACyclic; 26.07.2010