Search code examples
scalafor-comprehension

Problem in converting from for-comprehension to map


I'm trying to convert a Scala for comprehension into using map and I'm running into a problem.

For illustration, consider that following conversion that works as expected.

scala> for (i <- 0 to 10) yield i * 2
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

scala> 0 to 10 map { _ * 2 }
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20)

However, the following isn't working. What mistake am I making?

scala> import util.Random
import util.Random

scala> for (i <- 0 to 10) yield Random.nextInt(10)
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 0, 7, 5, 9, 4, 6, 6, 6, 3, 0)

scala> 0 to 10 map { Random.nextInt(10) }
<console>:13: error: type mismatch;
 found   : Int
 required: Int => ?
       0 to 10 map { Random.nextInt(10) }
                                   ^

The root cause might be either my inability to correctly decipher the error message or fixing the cause. As I review the signature of Random.nextInt it seems to be returning an Int.

scala> Random.nextInt
   def nextInt(n: Int): Int   def nextInt(): Int

Error message is saying that I need to provide a function that takes an Int and returns "something" (not sure what ? stands for).

required: Int => ?

So I can see that there is a mismatch. But how do I convert what I want to happen -- a call to Random.nextInt(10) -- into a function and pass it to map?

Any help in understanding the error message below would be appreciated.

scala> 0 to 10 map { Random.nextInt(10) }
<console>:13: error: type mismatch;
 found   : Int
 required: Int => ?
       0 to 10 map { Random.nextInt(10) }
                                   ^

(Edit)

Doing the following helped.

scala> def foo(x: Int): Int = Random.nextInt(10)
foo: (x: Int)Int

scala> 0 to 10 map { foo }
res10: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 1, 7, 6, 5, 1, 6, 0, 7, 4)

But comments on this or suggestions of recommended Scala-way to do this would be appreciated.


Solution

  • The Int => ? in the error message means than the compiler expects to see a function from Int to some other type (?). But Random.nextInt(10) is not a function, it's just an Int. You have to take an integer parameter:

    0 to 10 map { i => Random.nextInt(10) }
    

    You can also explicitly ignore the argument:

    0 to 10 map { _ => Random.nextInt(10) }
    

    or, even better, just use fill:

    Vector.fill(10){ Random.nextInt(10) }