Reputation: 35
I have:
val words = List("all", "the", "words", "all", "the", "counts", "all", "day")
val map = Exercise02.count(words.iterator)
val expected = Map("all" -> 3, "the" -> 2, "words" -> 1, "counts" -> 1, "day" -> 1)
where Exercise02.count
is java.util.Iterator[String] => Map[String, Int]
and merely produces a count of each word in the input java.util.Iterator[String]
.
I wrote a test:
object Exercise02Spec extends FlatSpec with Inspectors {
val words = List("all", "the", "words", "all", "the", "counts", "all", "day")
val map = Exercise02.count(words.iterator)
val expected = Map("all" -> 3, "the" -> 2, "words" -> 1, "counts" -> 1, "day" -> 1)
"count" should "count the occurrence of each word" in {
forAll (map) { kv => assert(kv._2 === expected(kv._1)) }
// forAll (map) { (k: String, v: Int) => assert(v === expected(k)) }
}
}
The first line compiles just fine, and the test passes. If I replace the first line with the commented out second line, I get a compilation error.
found : (String, Int) => Unit, required: ((String, Int)) => Unit
Type mismatch, expected: ((String, Int)) => Unit, actual: (String, Int) => Unit
Why is this? And how do I fix it?
Upvotes: 3
Views: 6899
Reputation: 4283
The method you're using accepts a function that transforms a single argument to a single output. What you're telling Scala in your second statement is that map should accept a function with two arguments! There's an important difference between a single argument that just happens to be a tuple of size two, and two distinct arguments.
So you have single argument, but you (and Scala) know it's a tuple. To access those two elements, you have to destructure or pattern match your argument against the tuple you want. You just do that by writing forAll (map) { case (k: String, v: Int) => assert(v === expected(k)) }
. You're saying the argument you receive should match the pattern of a tuple (String, Int)
and you want the first element bound to k
and the second to v
. You could probably eliminate mentioning the types explicitly here. Note that this is similar to the syntax used in pattern matching, which is essentially what you're doing here.
Upvotes: 3
Reputation: 16387
In the 2nd example you're defining a two argument function, not a single tuple argument function. Hence why the error is saying it is expecting the double parenthesis around the argument.
Upvotes: 0