У меня есть некоторые классы случая для сочетания суммы и произведения типов:Traverse/фолд вложенного класса дела в Scala без шаблонного кода
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
как зависимость, поэтому было бы предпочтительным решение, использующее эту библиотеку. Я открыт для включения новых зависимостей для решения этой проблемы.
Для моего конкретного примера определение не является рекурсивным, но мне было бы интересно увидеть решение, которое также работает для рекурсивных определений.
* Я знаю, как писать код для этого, но это будет утомительно. * Сначала покажите шаблонный паттерн; потом поговорим. – Jubobs