Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I call methods on a for-yield expression?

Tags:

scala

Say I have some Scala code like this:

// Outputs 1, 4, 9, 16, 25, 36, 49, 64, 81, 100
println( squares)

def squares = {
    val s = for ( count <- 1 to 10 )
                yield { count * count }
    s.mkString(", ");
}

Why do I have to use the temporary val s? I tried this:

def squares = for ( count <- 1 to 10 )
                  yield { count * count }.mkString(", ")

That fails to compile with this error message:

error: value mkString is not a member of Int
   def squares = for ( count <- 1 to 10 ) yield { count * count }.mkString(", ")

Shouldn't mkString be called on the collection returned by the for loop?

like image 418
1984isnotamanual Avatar asked Jun 02 '10 06:06

1984isnotamanual


3 Answers

There is a missing parenthesis. You want to call the mkString method on the result of the for-expression. Without the extra parenthesis the compiler thinks you wanted to call the mkString-method on {count * cout} which is an Int.

scala> def squares = (for ( count <- 1 to 10 ) yield { count * count }).mkString(", ")
squares: String

scala> squares
res2: String = 1, 4, 9, 16, 25, 36, 49, 64, 81, 100

Anyway I suggest you to should use the map method instead:

scala> 1 to 10 map { x => x*x } mkString(", ")
res0: String = 1, 4, 9, 16, 25, 36, 49, 64, 81, 100
like image 109
michael.kebe Avatar answered Nov 15 '22 07:11

michael.kebe


Just put parentheses around the for loop and it works:

scala> (for (count <- 1 to 10) yield { count * count }).mkString(", ") 

res0: String = 1, 4, 9, 16, 25, 36, 49, 64, 81, 100

like image 27
Arjan Blokzijl Avatar answered Nov 15 '22 05:11

Arjan Blokzijl


When you call mkString as you have in your second example, it's not being called on the collection but on each individual integer being returned, hence the error message: mkString is not a member of Int.
If you want to call methods on the for..yield expression itself, you'll need to parenthesize it:

def squares = (for (count <- 1 to 10) yield { count * count }).mkString(", ")
like image 28
tzaman Avatar answered Nov 15 '22 06:11

tzaman