Шаблон торта с переопределением абстрактного типа не работает с верхними границами типов

Я хочу переопределить абстрактный тип в черту с <: а не с = (например, ответ здесь Scala Upper Bounds: значение не является членом параметра типа).

Я хочу использовать шаблон торта, но это не работает, я не понимаю, почему?

trait A {
  def ping = println("ping")
}

trait Cake {
  type T
}

trait S { this: Cake =>
  type T = A
  def t: T
  t.ping
}

ОК, этот пример запускается, но в моем реальном случае я хочу переопределить тип с помощью <: а не с =. Кажется, невозможно получить доступ к функции t, почему?

trait S { this: Cake =>
  type T <: A
  def t: T
  t.ping
}

вернуть ошибку value ping is not a member of S.this.T

1 ответ

Решение

Это недостаток системы типов Scala. При определении членов в миксине Scala использует два правила: во-первых, конкретное всегда переопределяет абстрактное. Во-вторых, если два члена являются либо конкретными, либо обоими абстрактными, то побеждает тот, который придет позже в порядке линеаризации.

Кроме того, собственный тип черты

trait S { this: C => ... }

неявно увеличивается до

trait S { this: S with C => ... }

так что определения в признаке S могут быть доступны в пределах S. В вашем случае признак S рассматривается как:

trait S { this: S with Cake =>
  type T = A
  def t: T
  t.ping
}

Теперь, пока T конкретен, это нормально, потому что он переопределяет абстрактный T в Cake. Но если T является абстрактным, тот, что в Cake, появляется позже в порядке линеаризации и побеждает. И этот T не имеет верхней границы, поэтому член не пингуется. Один из способов исправить это - изменить порядок линеаризации, написав:

trait S { this: Cake with S =>
  type T <: A
  def t: T
  t.ping
}

Было бы лучше, если бы в Scala было другое правило, которое гласит, что все ограничения членов абстрактного типа объединяются в миксине, вместо того, чтобы выбирать один элемент в соответствии с порядком линеаризации. Это изменение, которое мы хотим рассмотреть в будущем, но мы должны быть осторожны с обратной совместимостью.

Другие вопросы по тегам