I canβt figure out how to handle overriding the β+β in an immutable map if the map can only store an invariant type for its values.
Sort of:
class FixedMap(val impl : Map[String, Int])
extends immutable.Map[String, Int] with immutable.MapLike[String, Int, FixedMap] {
// This should return FixedMap if B1 is Int, and Map[String,B1]
// if B1 is a superclass of Int; but there no way to do that.
// It is possible to return FixedMap here but then you have to
// throw at runtime if B1 is not Int
override def +[B1 >: Int](kv : (String, B1)) : Map[String, B1] = {
kv match {
case (k, v : Int) =>
new FixedMap(impl + Pair(k, v))
case _ =>
impl + kv
}
}
// ...
}
I would like this to work as methods that use CanBuildFromand always preserve the original type, if possible. Is there any way? Or should Map subclasses always leave the value type as the type parameter?
Here is a complete compiled example:
import scala.collection.immutable
// pointless class that wraps another map and adds one method
class FixedMap(val impl : Map[String, Int])
extends immutable.Map[String, Int] with immutable.MapLike[String, Int, FixedMap] {
override val empty : FixedMap = FixedMap.empty
// This should return FixedMap if B1 is Int, and Map[String,B1]
// if B1 is a superclass of Int; but there no way to do that.
// It is possible to return FixedMap here but then you have to
// throw at runtime if B1 is not Int
override def +[B1 >: Int](kv : (String, B1)) : Map[String, B1] = {
kv match {
case (k, v : Int) =>
new FixedMap(impl + Pair(k, v))
case _ =>
impl + kv
}
}
override def -(key : String) : FixedMap = {
new FixedMap(impl - key)
}
override def get(key : String) : Option[Int] = {
impl.get(key)
}
override def iterator : Iterator[(String, Int)] = {
impl.iterator
}
def somethingOnlyPossibleOnFixedMap() = {
println("FixedMap says hi")
}
}
object FixedMap {
val empty : FixedMap = new FixedMap(Map.empty)
}
object TestIt {
val empty = FixedMap.empty
empty.somethingOnlyPossibleOnFixedMap()
val one = empty + Pair("a", 1)
// Can't do the below because one is a Map[String,Int] not a FixedMap
// one.somethingOnlyPossibleOnFixedMap()
}
source
share