문제

Disclaimer: This is a question of what is possible, not what would be recommended in practice.

Let's say you're given the following classes:

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

and you have lists containing some number of each class

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

is it possible to create a list of a structural type that can contain all three point types using the usual techniques like ++, :::, or .union(..) without defining a common trait that all the classes extend, i.e.

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

I understand that as written above, the ::: operator returns a List[Product]. I assume it's a matter of providing the right hints to the Scala compiler, because the following code does produce a list of the correct type:

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);
})

Are there any hints I can give to help the Scala compiler to select the correct type for ::: and produce a List of the structural type specified?

도움이 되었습니까?

해결책

(points1 : List[{val x : Int; val y : Int}]) ::: points2 ::: points3

Should work!

다른 팁

If you want to write the following code:

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

It works:

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top