views:

213

answers:

1

The following code:

var m: Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3)

m = m filterKeys { s => s.length < 3 }

Does not compile. I get the following error:

error: type mismatch
found: collection.this.Map.Projection[scala.this.Predef.String,scala.this.Int]
required: collection.this.Map[scala.this.Predef.String,scala.this.Int]
m = m filterKeys { s => s.length < 3 }

I don't really understand this as according to the scaladoc a Projection[A,B] extends the trait Map[A,B+]. That is, a Projection is a Map.

I thought it might be something to do with the contravariant type B but if I use Any instead of Int, it still doesn't compile. What am I missing? The solution is to do:

var m: Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3)

m = Map(m filterKeys { s => s.length < 3 } toSeq : _ *)

but this seems inelegant to me.

A: 

OK - this has been figured out with the help of the scala console:

scala> var m = Map("A" -> 1, "BB" -> 2, "CCC" -> 3)
m: scala.collection.immutable.Map[java.lang.String,Int] = Map(A -> 1, BB -> 2, CCC -> 3)

So the type inference is inferring m's type as being an immutable map. The following code will compile OK:

var m: collection.Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3)
m = m filterKeys { s => s.length < 3 }

However, this is not much help as the map can not be added to in such a way as to return a collection.Map. I think that they should have overridden the ++ method inherited from Iterable with Map as the return type.

Could anyone comment on this? What use a collection.Map?

oxbow_lakes