2

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

ただし、Seqフィールドの代わりに子を格納するためにa を使用する場合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

いろいろ試してみましたが、何もうまくいきませんでした。Dataforの正しいインスタンスを記述する方法もわかりませんでしたSeq[...]

UPDATE : fromのDataインスタンスを適応させるとうまくいくようですListshapeless.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
  }
4

0 に答える 0