2
votes

What am I doing wrong? Where does String come from?

Scala code runner version 2.9.2 -- Copyright 2002-2011, LAMP/EPFL

scala> List(1).fold(Map()) { (m, x) => m + (x -> 1) }
<console>:9: error: type mismatch;
 found   : (Any, Int)
 required: String
              List(1).fold(Map()) { (m, x) => m + (x -> 1) }
                                                     ^

scala> List(1).foldLeft(Map()) { (m, x) => m + (x -> 1) }
<console>:9: error: type mismatch;
 found   : (Int, Int)
 required: (Nothing, Nothing)
              List(1).foldLeft(Map()) { (m, x) => m + (x -> 1) }
                                                         ^
1

1 Answers

4
votes

I'll answer in reverse order:

  • With the second error, your need to help type inference: the Scala compiler cannot know the type of Map() (it would need to look forward to the second parameter group, the operator, which it cannot do), so it infers it as Map[Nothing, Nothing](). And then trying to add an (Int, Int) to a Map[Nothing, Nothing] obviously won't work.

  • With the first error, you use fold, which requires a binary operator, with type (A,A) => A, so in your case probably (Int, Int) => Int, which isn't what you are looking for since your try to fold into a completely different type: foldLeft and foldRight can do that, however.

    Edit: it is looking for a String because it believes that m and x have to share the same type, so they have type Any (their only common supertype), which doesn't have a + method, but it has an implicit conversion that provides it for... String concatenation ; so it converts m to a String and then looks for another String on the other side of +. I know, this is sad.

You just need to annotate the types on Map:

scala> List(1).foldLeft(Map[Int, Int]()) { (m, x) => m + (x -> 1) }
res8: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)

Or, to show the intent in a clearer way:

scala> List(1).foldLeft(Map.empty[Int, Int]) { (m, x) => m + (x -> 1) }