Scala: смешивание черт с одним и тем же членом абстрактного типа - PullRequest
0 голосов
/ 25 мая 2018

Я смотрел на статью о системе типов Java и Scala, которая не работает.Чтобы лучше понять проблему, я пытался поиграть с меньшей проблемой.

У меня есть следующие типы:

class Parent
class Child extends Parent
class Grandchild extends Child
class GrandGrandchild extends Grandchild

Вот некоторые черты с ограниченными абстрактными типами:

trait LowerBound[T] extends{
  type M >: T
}

trait UpperBound[U] extends{
  type M <: U
}

Я понимаю, что здесь возникает проблема в том, что типы T и U в UpperBound и LowerBound не связаны между собой.Поэтому смешивать их может быть проблематично.

Я вижу, что могу создать объект / val, предоставив абстрактный тип:

object FamilyMember extends LowerBound[GrandGrandchild] with UpperBound[Parent] {
  type M = Child
}

, но мне не удается определить черту, как показано ниже:

trait FamilyTreeConstraint extends LowerBound[GrandGrandchild] with UpperBound[Parent]

Я получаю:

переопределение типа M в черте LowerBound с границами>: A $ A131.this.GrandGrandchild;тип M с чертой UpperBound с границами <: A $ A131.this.Parent имеет несовместимый тип </p>

Теперь, если у меня нет конкретных типов, параметризованный FamilyConstraint будет эквивалентен:

trait UpperLower[T,U]{
   type M >: T <: U
}

на котором я понимаю ошибку.поскольку T и U не связаны между собой.

Но приведенный выше тип семейных ограничений не является абстрактным и фактически имеет конкретные типы.Т.е. я бы вообразил, что компилятор в итоге получит следующее:

trait UpperLowerConcrete{
   type M >: GrandGrandchild <: Parent
}

Где мне будет позволено уточнить M как Child или GrandChild. Однако, это не превращается в выше и даетта же ошибка, что и в абстрактном случае.

  • Почему?

  • Кроме того, правильно ли я считаю, что сначала применяются уточнения типов, а затем проверяются ограничения типов?

1 Ответ

0 голосов
/ 26 мая 2018

Я не знаю причин такого поведения, но из моего опыта часто бывает необходимо явно переопределить определение type внутри подкласса / признака, если его ограничения изменены.Я имею в виду, что как только вы укажете ограничения для M явно в вашем FamilyTreeConstraint, компилятор будет удовлетворен

trait FamilyTreeConstraint extends LowerBound[GrandGrandchild] with UpperBound[Parent] {
  override type M >: Grandchild <: Parent
}

Смотрите это онлайн

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