继续使用Scala中的函数式编程,下一个练习是:
implement a bag in Scala
一个包包含一个 Map,其中每个键都等于元素的值,键的值是它在 Vector 中出现的次数。
bag(Vector("good", "dog", "good"))
=Map("good"-> 2, "dog" -> 1)
考虑mapMergeMonoid
:
// @author - pchiusano
def mapMergeMonoid[K,V](V: Monoid[V]): Monoid[Map[K,V]] =
new Monoid[Map[K, V]] {
def zero = Map()
def op(a: Map[K, V], b: Map[K, V]) =
a.map {
case (k, v) => (k, V.op(v, b.get(k).getOrElse(V.zero) ))
}
}
考虑我的实现bagWithMonoids
:
def bagWithMonoids[A](as: IndexedSeq[A]): Map[A, Int] = {
val bagMonoid: Monoid[Map[A, Int]] = mapMergeMonoid(intAddition)
as.map(x => Map(x -> 1)).foldLeft(bagMonoid.zero)
((acc, elem) => acc ++ bagMonoid.op(elem, acc))
}
为了使它更干净一点,我想(B, A) => B
将 foldLeft 的部分替换为bagMonoid.op
. 但是,当我这样做时,结果是Map()
.
我相信这是因为使用该参数bagMonoid.op(acc, elem)
会导致 ,这将导致Map()
因为acc
是一个空地图。
如何清理我的实现以bagMonoid.op
用作 foldLeft 的第二个参数?