Scalaz має поняття напівгрупи який відображає те , що ви хочете зробити тут, і призводить до можливо найкоротшому / найчистішому рішенням:
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> val map1 = Map(1 -> 9 , 2 -> 20)
map1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 9, 2 -> 20)
scala> val map2 = Map(1 -> 100, 3 -> 300)
map2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 100, 3 -> 300)
scala> map1 |+| map2
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 109, 3 -> 300, 2 -> 20)
Зокрема, двійковий оператор для Map[K, V]
об'єднання ключів карт, складання V
оператора напівгрупи над будь-якими повторюваними значеннями. Стандартна напівгрупа Int
використовує оператор додавання, тому ви отримуєте суму значень для кожного дублюючого ключа.
Редагувати : трохи детальніше, відповідно до запиту користувача482745.
Математично напівгрупа - це лише набір значень разом з оператором, який приймає з цього набору два значення, і виробляє інше значення з цього набору. Отже цілі числа, що знаходяться під додаванням, - це напівгрупа, наприклад - +
оператор поєднує два int, щоб зробити ще один int.
Ви також можете визначити напівгрупу над набором "всіх карт із заданим типом ключа та типом значення", якщо ви можете придумати деяку операцію, яка поєднує дві карти, щоб створити нову, яка є якимось чином поєднанням двох входи.
Якщо в обох картах немає клавіш, це тривіально. Якщо один і той же ключ існує в обох картах, то нам потрібно поєднати два значення, на які відображається ключ. Хм, хіба ми щойно не описали оператора, який поєднує два об'єкти одного типу? Ось чому в Scalaz напівгрупа for Map[K, V]
існує, якщо і лише тоді, коли Semigroup for V
існує - V
, то напівгрупа використовується для об'єднання значень з двох карт, які присвоєні одному ключу.
Отже, оскільки тут Int
є тип значення, "зіткнення" 1
ключа вирішується цілим додаванням двох відображених значень (як це робить оператор напівгрупи Int), отже 100 + 9
. Якби значення були Strings, зіткнення призвело б до об'єднання рядків двох відображених значень (знову ж таки, тому що це робить оператор напівгрупи для String).
(І що цікаво, тому що конкатенація рядків не є комутативною, тобто, "a" + "b" != "b" + "a"
одержувана в результаті операція напівгрупи теж не є. Так map1 |+| map2
це відрізняється від map2 |+| map1
випадку String, але не у випадку Int.)
map1 ++ map2