2

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
  }

0 Answers0