J'ai quelques classes de cas pour un mélange de somme et de types de produits:Traverse/plier une classe de cas imbriqué dans Scala sans le code boilerplate
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])
Je veux faire des opérations comme pli avec cette structure Top
. Voici quelques exemples:
- compter les occurrences de
BadLeaf
- Somme toutes les valeurs dans le
GoodLeaf
s
Voici un code qui effectue les opérations:
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)
}
La vie réelle la structure à laquelle je fais face est nettement plus compliquée que l'exemple que j'ai inventé. Y at-il des techniques qui pourraient m'aider à éviter d'écrire beaucoup de code standard?
J'ai déjà la bibliothèque cats
en tant que dépendance, donc une solution qui utilise cette bibliothèque serait préférable. Je suis ouvert à l'inclusion de nouvelles dépendances afin de résoudre ce problème.
Pour mon exemple particulier, la définition n'est pas récursive, mais je serais intéressé de voir une solution qui fonctionne également pour les définitions récursives.
* Je sais comment écrire du code pour faire ceci, mais ce sera fastidieux. * Montrer d'abord le passe-partout en question; ensuite nous parlerons. – Jubobs