我想在 Shapeless 中使用 Scrap Your Boilerplate 实现来操作某些案例类,但我一直在试图弄清楚如何让 SYB 组合everything
器遍历 type 的字段Seq[...]
。
例如,定义树如下:
abstract sealed class Tree[+A] extends Product with Serializable
case class Leaf[+A](value : A) extends Tree[A]
case class Node[+A](left : Tree[A], right : Tree[A]) extends Tree[A]
计算叶子的数量,下面的效果很好
object countLeaves extends Poly1 {
implicit def count[A] = at((a : Leaf[A]) => 1)
implicit def default[X] = at((x : X) => 0)
}
object sum extends Poly2 {
implicit final val add = at((i : Int, j : Int) => i + j)
}
scala> everything(countLeaves)(sum)(Node(Leaf(1), Leaf(2)))
res14: Int = 2
但是当使用 aSeq
来存储孩子而不是字段时Node
case class Node[+A](children : Seq[Tree[A]]) extends Tree[A]
然后everything
无法遍历字段 children :
scala> everything(countLeaves)(sum)(Node(Seq(Leaf(1), Leaf(2))))
res1: Int = 0
我尝试了各种方法,但没有任何效果。我也不知道如何编写Data
for的正确实例Seq[...]
。
更新:为from调整Data
实例似乎可行List
shapeless.Data
implicit def seqData[P, T, R](implicit qt: Lazy[shapeless.poly.Case1.Aux[P, T, R]]): Data[P, Seq[T], R] =
new Data[P, Seq[T], R] {
def gmapQ(t: Seq[T]) = t.map(qt.value(_)).toList
}