Параметры структурного типа в коллекциях Scala

Отказ от ответственности: это вопрос того, что возможно, а не того, что было бы рекомендовано на практике.

Допустим, вы получили следующие классы:

case class point1(x: Int, y:Int)
case class point2(x: Int, y:Int)
case class point3(x: Int, y:Int)

и у вас есть списки, содержащие некоторое количество каждого класса

val points1 = List[point1](/*Can be empty for this example*/)
val points2 = List[point2]()
val points3 = List[point3]()

Можно ли создать список структурного типа, который может содержать все три типа точек, используя обычные методы, такие как ++, :::, или же .union(..) без определения общей черты, которую расширяют все классы, т.е.

var points: List[{def x: Int; def y: Int}] = 
    points1 ::: points2 ::: points3

Я понимаю, что, как написано выше, ::: оператор возвращает List[Product], Я предполагаю, что это вопрос предоставления правильных подсказок компилятору Scala, потому что следующий код генерирует список правильного типа:

var points: ListBuffer[{def x: Int; def y: Int}] = List[{def x: Int; def y: Int}]()
points1.foreach( e => {
    val p: {def x: Int; def y: Int} = e;
    points.append(p);
})
points2.foreach( e => {
    val p: {def x: Int; def y: Int} = e;
    points.append(p);
})

Могу ли я дать какие-либо советы, которые помогут компилятору Scala выбрать правильный тип для ::: и составить список структурного типа, указанного?

2 ответа

Решение
(points1 : List[{val x : Int; val y : Int}]) ::: points2 ::: points3

Должно сработать!

Если вы хотите написать следующий код:

var points: List[{def x: Int; def y: Int}] = 
points1 ::: points2 ::: points3

Оно работает:

implicit def typer[B >: A, A <: { def x: Int; def y: Int }](t: List[B]): List[A] = t

var points: List[{def x: Int; def y: Int}] = 
points1 ::: points2 ::: points3
Другие вопросы по тегам