2016-11-02 10 views
1

私は、シェイプレスHMapを、同じ親を共有する他のオブジェクトのアグリゲーターとして機能するケースクラスの基礎構造として使用しています。親の特性では、arityというInt値のプロパティにアクセスできます。 HMapscanLeftを使用して、のオブジェクトの累積値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) 
    } 
} 
+0

の作動片である、' Poly2'パラメータを切り替えなければならない: '[T、INT] {(P、I)で=> iがpointCount(P)' – devkat

+0

を+ @devkatあなたが正しい、それはあなたの変更と一緒に動作します。これはありがとう!必要に応じて、回答を回答として追加することができます – sm01

答えて

0

@devkatのヒントを使用して解決することができました。ここでscanLeft` `のコード

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, LL <: HList](shapes: L) 
          (implicit 
           val ev: LUBConstraint[L, Shape], 
           val lf: LeftFolder.Aux[L, Int, pointAccumulate.type, Int], 
           val ls: LeftScanner.Aux[L, Int, pointAccumulate.type, LL], 
           val ev2: LUBConstraint[LL, Int]) { 

    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 default1[T <: Shape](implicit pt: pointCount.Case.Aux[T, Int]) = 
     at[T, Int] { (p, i) => i + pointCount(p) } 

    implicit def default2[T <: Shape](implicit pt: pointCount.Case.Aux[T, Int]) = 
     at[Int, T] { (i, p) => i + pointCount(p) } 
} 

object App2 { 

    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.parameterCount) 
     println(c.lookup) 
    } 
} 
関連する問題