Я смотрел на статью о системе типов 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
. Однако, это не превращается в выше и даетта же ошибка, что и в абстрактном случае.
Почему?
Кроме того, правильно ли я считаю, что сначала применяются уточнения типов, а затем проверяются ограничения типов?