java - Why does + operator on parameterized types in scala always result in string -
consider class follows:
import scala.collection.mutable.{hashmap => mutablehashmap} class customhashmap[k,v](hashmap: mutablehashmap[k,v], initval: v) { def addmaps(first: mutablehashmap[k, v], second: mutablehashmap[k, v]): mutablehashmap[k, v] = { second.foreach(pair => { first += (pair._1 -> (first.getorelse(pair._1, initval) + pair._2)) } ) //the above line throws compile time error first } //other functions }
upon adding 2 parameterized types there compile time error saying
expected (k,v) recieved (k,string)
i want know why scala implicit conversion? since operator overloading not allowed in java seemed logical in case of scala v class have method +
defined it.
here way how implement kind of thing manually:
since looks trying define monoid i'll take liberty move initval
addmaps
definition of operation.
this can done common typeclass pattern in scala, you'll have define manually +
means each type, want use in map.
basically have trait monoid
:
trait monoid[t] { def mzero: t // initval def madd(first: t, second: t): t // + operation }
than define implicit implementations each type extending trait. can define them in
- the companion object of
monoid
, it'll used automatically, - the companion object of class t, it'll used automatically,
- as implicit somewhere else, you'll have import manually.
here's example of monoid
companion object defining implementations strings , kinds of numbers:
object monoid { implicit object stringmonoid extends monoid[string] { def mzero = "" def madd(first: string, second: string) = first + second } implicit def numericmonoid[t](implicit ev: numeric[t]): monoid[t] = new monoid[t] { import numeric.implicits._ def mzero = ev.zero def madd(first: t, second: t) = first + second } }
then in addmaps
function request elements of maps should monoid
s, , use operations provided monoid implementation on elements:
def addmaps[k, v](first: mutablehashmap[k, v], second: mutablehashmap[k, v]) (implicit ev: monoid[v]): mutablehashmap[k, v] = { second.foreach { pair => first += (pair._1 -> ev.madd(first.getorelse(pair._1, ev.mzero), pair._2)) } first }
and here's test how works:
scala> addmaps(mutablehashmap(1 -> 2, 3 -> 4), mutablehashmap(1 -> 3, 5 -> 7)) res1: scala.collection.mutable.hashmap[int,int] = map(5 -> 7, 1 -> 5, 3 -> 4) scala> addmaps(mutablehashmap(1 -> "foo", 2 -> "bar"), mutablehashmap(1 -> "baz", 3 -> "qoo")) res2: scala.collection.mutable.hashmap[int,string] = map(2 -> bar, 1 -> foobaz, 3 -> qoo)
Comments
Post a Comment