Интересно, немного покопавшись, я получил следующее (на 2.7.5):
Общие карты:
def mergeMaps[A,B](collisionFunc: (B,B) => B)(listOfMaps: Seq[scala.collection.Map[A,B]]): Map[A, B] = {
listOfMaps.foldLeft(Map[A, B]()) { (m, s) =>
Map(
s.projection.map { pair =>
if (m contains pair._1)
(pair._1, collisionFunc(m(pair._1), pair._2))
else
pair
}.force.toList:_*)
}
}
Но человек, это отвратительно с проекцией и принуждением, списком и прочее. Отдельный вопрос: как лучше справиться с этим в сгибе?
Для изменчивых Карт, с которыми я имел дело в своем коде, и с менее общим решением, я получил это:
def mergeMaps[A,B](collisionFunc: (B,B) => B)(listOfMaps: List[mutable.Map[A,B]]): mutable.Map[A, B] = {
listOfMaps.foldLeft(mutable.Map[A,B]()) {
(m, s) =>
for (k <- s.keys) {
if (m contains k)
m(k) = collisionFunc(m(k), s(k))
else
m(k) = s(k)
}
m
}
}
Это выглядит немного чище, но будет работать только с изменяемыми Картами, как написано. Интересно, что сначала я попробовал описанное выше (до того, как задал вопрос), используя /: вместо foldLeft, но я получал ошибки типа. Я думал, что /: и foldLeft были в основном эквивалентны, но компилятор продолжал жаловаться, что мне нужны явные типы для (m, s). Что с этим?