I am trying to implement a map with default ratings , and I would like filters, maps, etc. they DefaultingMapalso produced DefaultingMapwhenever possible. Here is my initial implementation:
class DefaultingMap[K, V](defaultValue: => V)
extends mutable.HashMap[K, V]
with mutable.MapLike[K, V, DefaultingMap[K, V]] {
override def empty = new DefaultingMap[K, V](defaultValue)
override def default(key: K): V = {
val result = this.defaultValue
this(key) = result
result
}
}
I get type objects DefaultingMapwhen I use filter, but not when I use map:
scala> val counter = new DefaultingMap[Char, Int](0)
counter: DefaultingMap[Char,Int] = Map()
scala> for (c <- "ababcbbb") counter(c) += 1
scala> counter.filter{case (k, v) => v > 1}
res1: DefaultingMap[Char,Int] = Map((a,2), (b,5))
scala> counter.map{case (k, v) => (k, v * 2)}
res2: scala.collection.mutable.HashMap[Char,Int] = Map((a,4), (c,2), (b,10))
The difference between the two methods is that it mapaccepts implicit CanBuildFrom. Therefore, I understand that I need to have implicit defsomewhere to provide CanBuildFrom. My first intuition was to do what was done in HashMap:
object DefaultingMap extends generic.MutableMapFactory[DefaultingMap] {
def empty[K, V]: DefaultingMap[K, V] =
implicit def canBuildFrom[K, V]:
generic.CanBuildFrom[Coll, (K, V), DefaultingMap[K, V]] =
new MapCanBuildFrom[K, V]
}
, , , empty - , defaultValue. CanBuildFrom , -, , defaultValue.
?