Я использую бесформенный HMap
как базовую структуру класса case, действующего как агрегатор для других объектов, имеющих один и тот же родитель. Родительский признак позволяет получить доступ к Int-значному свойству, которое называется arity
. Я хотел бы использовать scanLeft
на HMap
для расчета совокупного arity
с объектов в HList
. Мне удалось записать объекты Poly
, позволяющие рассчитать сумму всех arity
с использованием foldLeft
, но при попытке применить те же понятия к scanLeft
он больше не работает.scanLeft с использованием HMap в бесформенном
Q1: Кто-нибудь видит, как я должен изменить pointAccumulate
для поддержки scanLeft
операций? Я ожидаю, что lookup
будет чем-то вроде этого Nat(2) :: Nat(5) :: Nat(8) :: HNil
(используя пример ниже).
Q2: Затем я буду использовать lookup
для поиска индекса элемента, знающего совокупную значимость в объединенной структуре. Учитывая это, было бы нормально работать с HList или я должен убедиться, что получаю lookup
в виде списка [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)
}
}
Для 'scanLeft', то' параметры Poly2' должны быть включены: 'на [T], Int {(р, я) => г + pointCount (р)' – devkat
@devat, вы правы, он работает с вашими изменениями. Спасибо за это! если вы хотите, вы можете добавить свой ответ в качестве ответа – sm01