Скажем, у меня есть два класса с одинаковым идентификатором для параметризованного типа
trait A {
type O
def f(a: Int, os: Seq[O]): Int
}
trait B {
type O
def g(a: Int, o: O): Int = { h1(o) + h2(a) }
def h1(o: O): Int
def h2(a: Int): Int = {a/2}
}
Я хотел бы создать дочерний класс, который будет "жениться" на двух
trait C extends A with B {
def f(a: Int, os: Seq[O]): Int = {
os.map{ o => g(a, o) }.sum
}
}
Наконец, я создаю реализацию для C
class D extends C {
type O = Int
def h1(o: O): Int = {5 * o}
}
При написании C
я пока не знаю, что это за тип O
- однако я бы хотел ограничить A.O == B.O
таким образом, что "имеет смысл" использовать B.g
в реализации A.f
. Я попытался реализовать это, и на удивление показалось, что Скала предположил, что был только один type O
val d = new D
println(d.f(1, Seq(1,2,3)))
Мне это кажется неправильным - почему A.O
и B.O
согласны?
EDIT
Я также хотел бы отметить, что если бы вы вместо этого наложили ограничения на O следующим образом,
case class Z()
case class Z1() extends Z
case class Z2() extends Z1
trait A {
type O <: Z
}
trait B {
type O >: Z2
}
class D extends C {
type O = Z1
Компиляция не удастся. Однако, если вы установите это вместо,
trait A {
type O <: Z
}
trait B {
type O <: Z1
}
class D extends C {
type O = Z2
Компиляция прошла успешно, и все работает нормально.