Reputation: 25
I am pretty new to scala, and i have hard time with generic in some case. I try to find simple example to illustrate my issue
let's start by setting 3 simple maps
scala> val map1 = Map[String, String]("A" -> "toto", "B" -> "tutu")
map1: scala.collection.immutable.Map[String,String] = Map(A -> toto, B -> tutu)
scala> val map2 = Map[String, Int]("B" -> 2)
map2: scala.collection.immutable.Map[String,Int] = Map(B -> 2)
scala> val map3 = Map[String, String]("A" -> "foo")
map3: scala.collection.immutable.Map[String,String] = Map(A -> foo)
if i merge using ++
scala> map1 ++ map2
res0: scala.collection.immutable.Map[String,Any] = Map(A -> toto, B -> 2)
My map became [String, Any] which is what i want to reproduce
I create new method in Map class
object MapUtils {
implicit class utils[K, V](map: Map[K, V]) {
def myUselessMethod(merge: Map[K, V]): Map[K, V] = {
map ++ merge
}
}
}
import MapUtils._
scala> map1 myUselessMethod map3
res4: Map[String,String] = Map(A -> foo, B -> tutu)
scala> map1 myUselessMethod map2
<console>:18: error: type mismatch;
found : scala.collection.immutable.Map[String,Int]
required: Map[String,String]
map1 myUselessMethod map2
How should i define my method so that it can return [String, Any]
I also checked scala MAP API to see if i can have some indications https://www.scala-lang.org/api/2.12.3/scala/collection/Map.html but
++[B >: (K, V), That](that: GenTraversableOnce[B])(implicit bf:
CanBuildFrom[Map[K, V], B, That]): That
is somehow indecipherable for me...
Thank you
Upvotes: 1
Views: 143
Reputation: 44908
Just give the compiler some slack in the return type:
object MapUtils {
implicit class utils[K, V](map: Map[K, V]) {
def myUselessMethod[L >: V](merge: Map[K, L]): Map[K, L] = {
map ++ merge
}
}
}
import MapUtils._
val map1 = Map[String, String]("A" -> "toto", "B" -> "tutu")
val map2 = Map[String, Int]("B" -> 2)
map1 myUselessMethod map2
Now it will infer the least upper bound L
of V
and the value type of the merge
-argument map. In case of Int
and String
, L
would be inferred to be Any
.
Upvotes: 1