I have just started to learn Scala.
When I was playing with an example in http://www.scala-lang.org/node/111 , I found a problem in types.
object Main extends App {
def even(from: Int, to: Int): Vector[Int] =
for (i <- from until to if i % 2 == 0) yield i
Console.println(even(0, 20).getClass())
}
This does not compile with the following error.
<console>:9: error: type mismatch;
found : scala.collection.immutable.IndexedSeq[Int]
required: Vector[Int]
for (i <- from until to if i % 2 == 0) yield i
^
However, without type specification of return value, It works and the class is Vector.
object Main extends App {
def even(from: Int, to: Int) =
for (i <- from until to if i % 2 == 0) yield i
Console.println(even(0, 20).getClass()) // => class scala.collection.immutable.Vector
}
This seems to be contradict. Let me know what is the cause of the compile type error.
You are confusing classes with types. The type of the value yielded by the for-expression is IndexedSeq[Int]
, which happens to be implemented by a Vector instance. You specified in the signature that the return type must be Vector[Int]
, but the for-expression gives no such guarantee.
edit to add: you'll notice in the example on the website that they use the List.range
method to produce the generator in the for-expression, and that's how they get a return type of List[Int]
. If you use the Vector.range
method (rather than the until
method, which produces a Range
) then you will be filtering a Vector
and the compiler will infer this as the return type.
If you want to see they type of an expression or function, the REPL tells you when you define or evaluate it:
scala> def even(from: Int, to: Int) =
| for (i <- from until to if i % 2 == 0) yield i
even: (from: Int, to: Int)scala.collection.immutable.IndexedSeq[Int]
// ^ here!