scalatest - Confusing type mismatch in Scala


Question: 

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.

  • sbt reports: found : (String, Int) => Unit, required: ((String, Int)) => Unit
  • IntelliJ IDEA reports: Type mismatch, expected: ((String, Int)) => Unit, actual: (String, Int) => Unit

Why is this? And how do I fix it?




2 Answers: 

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.

 

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.

 

More Articles


email - PHP mail function not working based on the body of the message

so on my server I tried running:mail('my@email.com', 'asdf', 'asklfdjksalfdsdaf I know I I know I');and PHP sent the mail perfectly....but then when I changed the message to mail('my@email.com', 'asdf', 'hahahahaa');it did NOT send the email to me....what can possibly cause this? the only thing that

Computer Networks ip addressing

So I have this exercise in one of my classes on network ip addressing. The problem is that i cant figure out how to complete the subnet bits and hosts bits..can anyone help me?the number of hosts is 414, 189, 135 and 90...

javascript - less.js: Use custom import function

less.js is using an internal xhr() function to load @imported .less files dynamically via ajax.I want to know if there is anything I can do the hand a custom function over to the less parser to get the imported files loaded through this function and NOT through the default loading function.As a wild


php - Laravel default selection on form when loading page

I have a select tag on a form, and I want to populate a default option, this default option will be the one that is searched. I can get it through something like $_GET but it does not work in my case, as I am looping through and getting all the values from the database. <select name="location"&

exchange server - What e-mail address ("From" vs. "Mail From") is considered by my block list?

We are getting a lost of spam /phishing e-mails where the [From] is showing our own domain (e.g. "john@foobar.com"), but the [Mail From] (return-path) in the e-mail header is showing "root@foo-574401.hostbar.com".Question is now, which e-mail address is actually considered by the Exchange Online blo

Apply function to one element of a list in Python

I'm looking for a concise and functional style way to apply a function to one element of a tuple and return the new tuple, in Python.For example, for the following input:inp = ("hello", "my", "friend")I would like to be able to get the following output:out = ("hello", "MY", "friend")I came up with t


authentication - Sitecore - Prevent access to a page, but still show it in the navigation

In Sitecore I have denied access to a particular page for the anonymous user. This works correctly, but it also means that the page does not appear in the navigation menus and sitemap (both XSLT).What I would like is for the user to be able to see the link, but be redirected to a Register/Login page

scala - Should I use collectionAsScalaIterable({java collection}) or Seq({java collection}).flatten?

We're starting to use Scala Test to test our Java application, and I want to test the contents of a Java Collection. We came up with 2 possibilities:JavaConversions.collectionAsScalaIterable(getJavaCollection()) must contain(allOf(item1, item2).inOrder)orSeq(getJavaCollection()).flatten mustEqual Se

Revert from Python 2.7 to Python 2.6 in Mac OSX 10.6.8 doesn't work even though I've uninstalled Python 2.7

I have mac OSX 10.6.8. My system came with Python 2.6I recently installed Python 2.7 but experienced many problems with it so decided to revert back to Python 2.6 by executing $ sudo rm -rf /Library/Frameworks/Python.framework/Versions/2.7I also removed Python 2.7 from my Applications folder. Still

How do I access my website (IIS) from the internet?

I have installed IIS. I have browsed to my website on IIS using the 'Browse *:80 (http)' link in IIS. This navigates to http://localhost. That link is only going to work on my own machine.I don't care about my IP address changing (I'm going to show my website for a few hours max every now and the