1
votes

First, here are 3 snippets of code along with their output on Scala 2.10.2

// 1.
def one: Seq[List[String]] =
  Seq(List("x")) ++ List(List("x"))
println(one)
// => List(List(x), List(x)))

// 2.
def two: List[List[String]] =
  Seq(List("x")) ++ List(List("x"))
println(two)
// =>
// error: type mismatch;
//  found   : Seq[List[String]]
//  required: List[List[String]]
//   Seq(List("x")) ++ List(List("x"))
// one error found

// 3.
println(Seq(List("x")) ++ List(List("x")))
// => List(List(x), List(x))

The main code in all the 3 snippets is the same -- Seq(List("x")) ++ List(List("x"))

The first and the third snippet show (print) the type as List[List[String]], but the second snippet, which specifies the return type as List[List[String]] fails to compile. The first one's return type is Seq[List[String]] but it's printed as a List[List[String]].

What exactly is happening here?

2

2 Answers

3
votes

The return type of the second snippet is List[List[String]], but the value has type Seq[List[String]], this is were exception occurs. List is a subclass of Seq, it's more concrete type. println prints out values you have, but not their types, if you want to see the actual type of an expression, print it in the Scala REPL:

scala> Seq(List("x")) ++ List(List("x"))
res5: Seq[List[String]] = List(List(x), List(x))

see res5 type is infered as Seq[List[String]], but the value is List(List(x), List(x)). List is a case class with automatically overriden toString method, which, for readability is overriden by the compiler.

0
votes

The second snippet doesn't compile because Seq.++ returns a scala.collection.Seq (see the ScalaDoc), which is not a scala.collection.immutable.List:

def ++[B](that: GenTraversableOnce[B]): Seq[B]

See also this question.