Почему я не могу вызвать методы для выражения for-yield?

Скажем, у меня есть код Scala, как это:

// 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(", ");
}

Почему я должен использовать временные val s? Я пробовал это:

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

Что не удается скомпилировать с этим сообщением об ошибке:

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

Не следует ли вызывать mkString в коллекции, возвращаемой циклом for?

Ответ 1

Отсутствует скобка. Вы хотите вызвать метод mkString в результате выражения for -expression. Без дополнительной скобки компилятор считает, что вы хотите называть mkString -метод на {count * cout}, который является 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

В любом случае, я предлагаю вам использовать метод map:

scala> 1 to 10 map { x => x*x } mkString(", ")
res0: String = 1, 4, 9, 16, 25, 36, 49, 64, 81, 100

Ответ 2

Просто поместите круглые скобки вокруг цикла for, и он работает:

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

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

Ответ 3

Когда вы вызываете mkString, как у вас во втором примере, он не вызывается в коллекции, а на каждом возвращаемом отдельном целое, поэтому появляется сообщение об ошибке: mkString is not a member of Int.
Если вы хотите вызвать методы в самом выражении for..yield, вам необходимо заключить в скобки:

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