您可以scalaz.std.tuple.tuple2Monoid
显式使用您想要的两个幺半群:
import scalaz.Monoid
implicit val countMonoid: Monoid[(Int, Double)] = scalaz.std.tuple.tuple2Monoid(
Monoid.instance[Int](math.min(_, _), Int.MaxValue),
Monoid.instance[Double](_ + _, 0)
)
进而:
scala> import scalaz.std.map._, scalaz.syntax.monoid._
import scalaz.std.map._
import scalaz.syntax.monoid._
scala> val map1 = Map("a" -> (1, 5.0), "b" -> (2, 4.0), "c" -> (3, 8.0))
map1: scala.collection.immutable.Map[String,(Int, Double)] = Map(a -> (1,5.0), b -> (2,4.0), c -> (3,8.0))
scala> val map2 = Map("b" -> (4, 1.0))
map2: scala.collection.immutable.Map[String,(Int, Double)] = Map(b -> (4,1.0))
scala> val merge = map1.toMap |+| map2.toMap
merge: scala.collection.immutable.Map[String,(Int, Double)] = Map(a -> (1,5.0), b -> (2,5.0), c -> (3,8.0))
scala> val map2 = Map("d" -> (4, 1.0))
map2: scala.collection.immutable.Map[String,(Int, Double)] = Map(d -> (4,1.0))
scala> val merge2 = map1.toMap |+| map2.toMap
merge2: scala.collection.immutable.Map[String,(Int, Double)] = Map(a -> (1,5.0), b -> (2,4.0), c -> (3,8.0), d -> (4,1.0))
但是,这并不理想,因为该类型(Int, Double)
可用于表示许多不同的事物,并且您刚刚定义了一个可能会出现在您或您的用户未预料到的地方的 monoid 实例。我个人会改用案例类:
case class Count(order: Int, number: Double)
然后在Count
伴生对象中定义实例,显式地或通过countMonoid
上面的和一个IsoSet[Count, (Int, Double)]
.