Skip to content

Instantly share code, notes, and snippets.

@herval
Created April 18, 2016 14:37
Show Gist options
  • Save herval/8d47a29f767e97021da2e3595c7f0b37 to your computer and use it in GitHub Desktop.
Save herval/8d47a29f767e97021da2e3595c7f0b37 to your computer and use it in GitHub Desktop.
Manipulating maps with Monoids
object MindBlown extends App {
trait Monoid[A] {
def op(a1: A, a2: A): A
def zero: A
}
val intAddition = new Monoid[Int] {
override def op(a1: Int, a2: Int) = a1 + a2
override def zero = 0
}
def mapMergeMonoid[K, V](V: Monoid[V]): Monoid[Map[K, V]] = new Monoid[Map[K, V]] {
def zero = Map[K, V]()
def op(a: Map[K, V], b: Map[K, V]) =
(a.keySet ++ b.keySet).foldLeft(zero) { (acc, k) =>
acc.updated(k, V.op(a.getOrElse(k, V.zero),
b.getOrElse(k, V.zero)))
}
}
// Add numbers for the same keys on a map of maps
val merging: Monoid[Map[String, Map[String, Int]]] = mapMergeMonoid(mapMergeMonoid(intAddition))
val m1 = Map("o1" -> Map("i1" -> 1, "i2" -> 2))
val m2 = Map("o1" -> Map("i2" -> 3))
val m3 = Map("o1" -> Map("i2" -> 2))
println(merging.op(merging.op(m1, m2), m3)) // Map(o1 -> Map(i1 -> 1, i2 -> 7))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment