Scala - Использование внутренних определений типов обобщенных c параметров типа не компилируется - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь определить арифметическое c представление дерева выражений. DataElement представляет одну пару ключ-значение. CalcElement представляет пару подэлементов (Cal c или Data). Для CalcElement ключ является набором ключей из подэлементов. Значение для CalcElement является комбинацией значений подэлементов с использованием метода apply.

Следующий код не компилируется, и я пытаюсь выяснить, почему он не должен.

trait DataElement[K] {
  type KeyType = K
  def key:KeyType
  def value:Double
}

trait CalcElement[OP1<:DataElement[_], OP2<:DataElement[_]] extends DataElement[(OP1#KeyType, OP2#KeyType)] //FIRST ERROR
{
  def op1: OP1
  def op2: OP2

  def apply: (OP1, OP2) => Double
  def unapplyFirst: (Double, OP1) => OP2
  def unapplySecond: (Double, OP2) => OP1

  def key: (OP1#KeyType, OP2#KeyType) = (op1.key, op2.key) // SECOND AND THIRD ERROR
  def value: Double = apply(op1, op2)
}

ПЕРВАЯ ОШИБКА

Error:(12, 84) illegal inheritance;
 self-type CalcElement[OP1,OP2] does not conform to DataElement[(_$1, _$2)]'s selftype DataElement[(_$1, _$2)]
trait CalcElement[OP1<:DataElement[_], OP2<:DataElement[_]] extends DataElement[(OP1#KeyType, OP2#KeyType)]

ВТОРАЯ и ТРЕТЬЯ ОШИБКИ

Error:(21, 46) type mismatch;
 found   : (some other)_$1(in type OP1)
 required: _$1(in type OP1)
  def key: (OP1#KeyType, OP2#KeyType) = (op1.key, op2.key)
Error:(21, 55) type mismatch;
 found   : (some other)_$2(in type OP2)
 required: _$2(in type OP2)
  def key: (OP1#KeyType, OP2#KeyType) = (op1.key, op2.key)

Может помочь в понимании образа мышления компиляторов здесь.

Cheers

1 Ответ

1 голос
/ 13 февраля 2020

В вашем примере KeyType не определен, пока не будет создан тип. Следовательно, OP1 # KeyType и OP2 # KeyType не будут работать.

Либо сделайте это:

trait CalcElement[OP1<:DataElement[Double], OP2<:DataElement[Double]] 
extends DataElement[(OP1#KeyType, OP2#KeyType)]

ИЛИ это:

trait CalcElement[X, Y, OP1<:DataElement[X], OP2<:DataElement[Y]] 
extends DataElement[(OP1#KeyType, OP2#KeyType)]

То, чем я не являюсь В состоянии понять, почему вам нужно передать KeyType для создания DataElement? Поскольку вычисление может быть древовидным, следовательно, почему оно не может быть таким:

trait CalcElement[OP1<:DataElement[_], OP2<:DataElement[_]] 
extends DataElement[(OP1, OP2)]

?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...