Scala结合了地图,同时使用Scalaz半群处理与自定义类型的碰撞

时间:2015-12-01 23:04:35

标签: scala scalaz

    case class Special(foo: Bar) {

    }
    case class SpecialMap(bar: Map[SpecialKey, Special]) {
           //I want to be able to do
           def combineValuesMap(that: SpecialMap) : SpecialMap = {
               this.bar |+| that.bar
           }
    }

我已经尝试过重载+但是没有让我执行。如何创建一个允许我使用半群来执行此操作的特殊类型?

参考| + | :Best way to merge two maps and sum the values of same key?

1 个答案:

答案 0 :(得分:1)

您需要为Special类型提供半群实例。像这样的实例的“最佳”位置是该类型的伴随对象,因为那里定义的实例将自动可用:

case class Special(foo: String)

object Special {
  import scalaz.Semigroup

  implicit val semigroupSpecial: Semigroup[Special] = Semigroup.instance(
    (specialA, specialB) => Special(s"(${specialA.foo}-${specialB.foo})")
  )
}

(请注意,我正在简化一下,但在你的情况下,这个想法会是一样的。)

然后:

import scalaz.std.map._, scalaz.syntax.semigroup._

val m1 = Map("a" -> Special("a"), "b" -> Special("b"))
val m2 = Map("c" -> Special("c"), "b" -> Special("another b"))
val m3 = m1 |+| m2

这将使用您提供的组合函数来组合碰撞时的值:

scala> m3.foreach(println)
(c,Special(c))
(b,Special((b-another b)))
(a,Special(a))

这就是你想要的。