私は、シェイプレスHMap
を、同じ親を共有する他のオブジェクトのアグリゲーターとして機能するケースクラスの基礎構造として使用しています。親の特性では、arity
というInt値のプロパティにアクセスできます。 HMap
のscanLeft
を使用して、のオブジェクトの累積値arity
を計算したいと思います。私はオブジェクトを書いて成功しました。を使ってすべての和を計算することを可能にしましたが、同じ概念をscanLeft
に適用しようとするともう機能しません。シェイプレスでHMapを使用するscanLeft
質問scanLeft
の操作をサポートするために、pointAccumulate
をどのように修正する必要がありますか? lookup
は、Nat(2) :: Nat(5) :: Nat(8) :: HNil
のようなものになると期待しています(下の例を使用してください)。
Q2:後でlookup
を使用して、結合構造内の累積率を知る要素のインデックスを検索します。これを考えると、HListで作業するのは大丈夫でしょうか、lookup
をList [Int]にする必要がありますか?
import shapeless._
import ops.hlist.{At, LeftFolder, LeftScanner}
object Point { type Point = (Double, Double) }
import Point._
sealed trait Shape {
val arity: Int
}
case class Line(p0: Point, p1: Point) extends Shape {
val arity = 2
}
case class Triangle(p0: Point, p1: Point, p2: Point) extends Shape {
val arity = 3
}
case class Canvas[L <: HList](shapes: L)
(implicit
val ev: LUBConstraint[L, Shape],
val lf: LeftFolder.Aux[L, Int, pointAccumulate.type, Int],
val ls: LeftScanner[L, Int, pointAccumulate.type]) {
lazy val parameterCount: Int = shapes.foldLeft(0)(pointAccumulate)
lazy val lookup = shapes.scanLeft(0)(pointAccumulate)
}
object pointCount extends Poly1 {
implicit def default[T <: Shape] = at[T](_.arity)
}
object pointAccumulate extends Poly2 {
implicit def default[T <: Shape](implicit pt: pointCount.Case.Aux[T, Int]) =
at[Int, T] { (i, p) => i + pointCount(p) }
}
object App {
def main(args: Array[String]): Unit = {
val l0 = Line((-2, 2), (2, -2))
val tr1 = Triangle((0,0), (0, 1), (1, 0))
val tr2 = Triangle((1,1), (1, 2), (2, 1))
val c = Canvas(l0 :: tr1 :: tr2 :: HNil)
println(c.lookup)
}
}
の作動片である、' Poly2'パラメータを切り替えなければならない: '[T、INT] {(P、I)で=> iがpointCount(P)' – devkat
を+ @devkatあなたが正しい、それはあなたの変更と一緒に動作します。これはありがとう!必要に応じて、回答を回答として追加することができます – sm01