Search code examples
scalafunctional-programmingfor-comprehension

Inverting a map in Scala


I'm doing a course in Coursera about Scala functional programming. I'm in the 6th week.

I have the following code:

/* define the map of numbers to letters */ 
val nmem = Map(
  '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", 
  '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ"
)

/* invert the map to get a map of letters to digits */
val charCode: Map[Char, Char] = 
  for {
       (digit, str) <- nmem
       ltr <- str
  } yield ltr -> digit

My question is how does the for-comprehension work? nmem introduces the key (char) and the value (string) into digit and str. And later we have: ltr <- str which I don't know how it works because I don't understand how the program knows that ltr is a char instead of an string.

Thank you in advance.


Solution

  • This for-comprehension is desugared into

    nmem.flatMap { case (digit, str) => str.map { ltr => (ltr, digit) } }
    

    Since nmem has type Map[Char, String], the compiler knows that (digit, str) must be of type (Char, String). Thus, it knows that str is of type String. The elements of a String are of type Char, thus the type of ltr is inferred to be Char.

    If you wanted to write down all the gory details of the type inference, you would get something like this:

    nmem.flatMap[(Char, Char), Map[Char, Char]]{ 
      case (digit: Char, str: String) => 
      str.map[(Char, Char), Seq[(Char, Char)]]{ 
        (ltr: Char) => (ltr, digit) 
      } 
    }
    

    Fortunately, this is not necessary, because all those types can be inferred automatically.