To complement dhg's answer :
First, to use |+|
on a Map[A, B]
we need a Semigroup[B]
instance. In this case Semigroup[Double]
. But scalaz itself doesn't give you this instance, because it wouldn't follow the rules/laws of a correct Semigroup
instance (related scalaz issue).
No despair, because we can still get an instance from the project scalaz-outlaws (which only supports scalaz 7.1.x it seems). Using the Double
outlaw instance we can now combine two Double
s, while ignoring the deprecation message urging us not to use Monoid[Double]
because it doesn't uphold the laws :
import scalaz.syntax.semigroup._
import scalaz.outlaws.std.double._
1.0 |+| 2.0
// <console>:18: warning: value doubleMonoid in trait DoubleOutlawInstances
// is deprecated: Monoid[Double] violates the associativity law
// 1.0 |+| 2.0
// ^
// res0: Double = 3.0
Second, we can simplify the reduce
/ fold
with scalaz by using the Monoid[Double]
implicitly instead of using |+|
directly.
import scalaz.std.map._
import scalaz.outlaws.std.double._
import scalaz.syntax.foldable._
val map = Map("U1" -> Map("a"-> 2.1, "b"->3.21, "c"->7.1),
"U2" -> Map("a"-> 3.1, "b"->12.1, "c"->1.4))
map.concatenate
// Map[String,Double] = Map(a -> 5.2, b -> 15.309999999999999, c -> 8.5)
The map.concatenate
is analogous to
map.values.fold(Monoid[Map[String, Double]].zero)(_ |+| _)