Reputation: 3497
I define the following List of tuples:
var temps = Seq(("Spain", Seq(68,70,73,75)),
("Trinidad",Seq(87,83,88,84,88)),
("England",Seq(52,55,58,57.5)),
("Eritrea",Seq(90,91.3,88,91)))
and the resulting type is as follows:
temps: Seq[(String, Seq[AnyVal])] = List((Spain,List(68, 70, 73, 75)), (Trinidad,List(87, 83, 88, 84, 88)), (England,List(52.0, 55.0, 58.0, 57.5)), (Eritrea,List(90.0, 91.3, 88.0, 91.0)))
My question is why the type of temps is inferred as Seq[(String, Seq[AnyVal])]
rather than Seq[(String, Seq[Int])] or Seq[(String, Seq[Double])]
which is what one would expect ?
I am a Scala newbie so pardon me if there is a simple explanation.
Upvotes: 3
Views: 421
Reputation: 16412
This is how type inference works. Scala can infer type in a context/declaration scope, but not across contexts as in here. For example this works:
scala> val ss = Seq(Seq(1, 1.2))
ss: Seq[Seq[Double]] = List(List(1.0, 1.2))
Although we have both Int
and Double
, Int
gets promoted up.
However, this does not work:
scala> val ss = Seq(Seq(1, 1.2), Seq(2, 2))
ss: Seq[Seq[AnyVal]] = List(List(1.0, 1.2), List(2, 2))
because first list becomes Seq[Double]
and second one - Seq[Int]
. To find common super type scala reverts to Seq[AnyVal]
.
You can explicitly annotate the declaration to help compiler resolve the ambiguity:
scala> val ss: Seq[Seq[Double]] = Seq(Seq(1, 1.2), Seq(2, 2))
ss: Seq[Seq[Double]] = List(List(1.0, 1.2), List(2.0, 2.0))
Upvotes: 5