我有一些用于 sum 和 product 类型混合的案例类:
sealed trait Leaf
case class GoodLeaf(value: Int) extends Leaf
case object BadLeaf extends Leaf
case class Middle(left: Leaf, right: Leaf)
case class Container(leaf: Leaf)
case class Top(middle : Middle, container: Container, extraLeaves : List[Leaf])
我想用这种Top
结构做一些类似折叠的操作。示例包括:
- 计算出现次数
BadLeaf
GoodLeaf
将s中的所有值相加
这是一些执行操作的代码:
object Top {
def fold[T](accu: T)(f : (T, Leaf) => T)(top: Top) = {
val allLeaves = top.container.leaf :: top.middle.left :: top.middle.right :: top.extraLeaves
allLeaves.foldLeft(accu)(f)
}
private def countBadLeaf(count: Int, leaf : Leaf) = leaf match {
case BadLeaf => count + 1
case _ => count
}
def countBad(top: Top): Int = fold(0)(countBadLeaf)(top)
private def sumGoodLeaf(count: Int, leaf : Leaf) = leaf match {
case GoodLeaf(v) => count + v
case _ => count
}
def sumGoodValues(top: Top) = fold(0)(sumGoodLeaf)(top)
}
我正在处理的现实生活结构比我编造的例子要复杂得多。是否有任何技术可以帮助我避免编写大量样板代码?
我已经将该cats
库作为依赖项,因此首选使用该库的解决方案。为了解决这个问题,我愿意包含新的依赖项。
对于我的特定示例,定义不是递归的,但我有兴趣看到一个也适用于递归定义的解决方案。