I want to use the Scrap Your Boilerplate implementation in Shapeless to operate on some case classes but i'm stuck trying to figure out how to make the SYB combinator everything traverse a field of type Seq[...].
For example, defining trees like:
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]
to count the number of leaves, the following works very well
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
But when using a Seq to store the children instead fields in Node
case class Node[+A](children : Seq[Tree[A]]) extends Tree[A]
then everything is not able to traverse the field children :
scala> everything(countLeaves)(sum)(Node(Seq(Leaf(1), Leaf(2))))
res1: Int = 0
I tried various things but nothing worked. I did not figure out either how to write a correct instance of Data for Seq[...].
UPDATE : Adapting the Data instance for List from shapeless.Data seems to work out
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
}