views:

109

answers:

2

According to the scaladoc for the map method on a Map object, it should return a new Map:

 def   map  [B]  (f: ((A, B)) ⇒ B)  : Map[B]   

"returns a new map resulting from applying the given function f to each element of this map and collecting the results. "

But it doesn't:

scala> val countries = Map("NO" -> "Norway", "US" -> "United States", "DE" -> "Germany")
countries: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((NO,Norway), (US,United States), (DE,Germany))

countries map { _._1 }
res4: scala.collection.immutable.Iterable[java.lang.String] = List(NO, US, DE)

This behaviour is what I would expect, though. So is the documentation wrong, or am I missing something?

+5  A: 

You are reading the wrong map function.

def map [B] (f: ((A, B)) ⇒ B) : Map[B]

But you are using:

def map [B, That] (f: ((A, B)) ⇒ B)(implicit bf: CanBuildFrom[Map[A, B], B, That]) : That

Since you are returning a String you are not using the fist but the second. And for it the ScalaDoc says:

"a new collection of type That resulting from applying the given function f to each element of this map and collecting the results."

Francisco Casanova
That sort of make sense. But I think the docs could be clearer at this point, since the "use case" that was supposed to simplify the understanding of these complex method signatures actually makes it more confusing in this case. The results are intuitive though, which may be most important.
Knut Arne Vedaa
They are both the same function. As retronym points out, the simpler one is an incorrect @usecase.
Ben Lings
+4  A: 

The @usecase addition to Scaladoc was fairly hastily conceived and implemented, and has a few wrinkles. In this case, the use case is defined in the Scaladoc for TraversableLike#map:

@usecase def map[B](f: A => B): $Coll[B]

$Coll is replaced with simple text substitution, using the value defined in scala.collection.Map.

/**
 *  @define Coll Map
 *  @define coll map
 */
object Map extends MapFactory[Map]

What could be done about this? Perhaps the result of the text substitution could be type checked, which would rule out these edge cases.

retronym