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 monoids, , 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