scala - shapeless Mapper for LabelledGeneric not found -
i have basic type pool defined that:
sealed trait section final case class header(...) extends section final case class customer(...) extends section final case class supplier(...) extends section final case class tech(...) extends section
i'd present case classes composed of types pool this:
final case class contractviewpartners(customer: customer, supplier: supplier) final case class contractview(header: header, partners: contractviewpartners, tech: tech)
as heavily used in feature-generators implemented via transfoming hlist
s using method described here, i'd ensure each field of presented type 1 of
section
subtypehlist
ofsection
subtypes- record presentable
hlist
ofsection
subtypes
i've defined simple compile-time checker condition:
object traverseview extends poly1 { implicit def casesection[s <: section] = at[s](_ => ()) implicit def casesectionlist[l <: hlist] (implicit evt: totraversable.aux[l, list, section]) = at[l](_ => ()) implicit def caserecord[r, l <: hlist] (implicit lgen: labelledgeneric.aux[r, l], trav: totraversable.aux[l, list, section]) = at[r](_ => ()) } private def contractviewismultisection(v: contractview) = { val gen = labelledgeneric[contractview].to(v) gen map traverseview }
but fails (package names removed)
could not find implicit value parameter mapper: mapper[traverseview.type,::[header keytag[symbol tagged[string("header")],header],::[contractviewpartners keytag[symbol tagged[string("partners")],contractviewpartners],::[tech keytag[symbol tagged[string("tech")],tech],hnil]]]]
if remove partners
section contractview
it's working , if try resolve implicits
on contractviewpartners
found too.
again while writing question i've found solution adding .values
that
private def contractviewismultisection(v: contractview) = { val gen = labelledgeneric[contractview].to(v) .values //!!! gen map traverseview }
could type with keytag[...]
not working source labelledgeneric
transformation?
the problem case
invariant, fact have case
instance contractviewpartners
doesn't mean have case instance contractviewpartners
type-level label (which subtype of contractviewpartners
). can fix pretty straightforwardly generating instances e.g. fieldtype[k, contractviewpartners]
(for arbitrary k
):
sealed trait section final case class header(s: string) extends section final case class customer(s: string) extends section final case class supplier(s: string) extends section final case class tech(s: string) extends section final case class contractviewpartners(customer: customer, supplier: supplier) final case class contractview(header: header, partners: contractviewpartners, tech: tech) import shapeless._, labelled.fieldtype, ops.hlist.tolist object traverseview extends poly1 { implicit def casesection[s <: section] = at[s](_ => ()) implicit def casesectionlist[k, l <: hlist](implicit lub: tolist[l, section] ) = at[fieldtype[k, l]](_ => ()) implicit def caserecord[k, c, l <: hlist](implicit gen: generic.aux[c, l], lub: tolist[l, section] ) = at[fieldtype[k, c]](_ => ()) } private def contractviewismultisection(v: contractview) = { val gen = labelledgeneric[contractview].to(v) gen map traverseview }
you use generic[contractview]
in contractviewismultisection
if don't care labels.
i suggest not using poly1
kind of thing, though. if want evidence types right, little more cleanly custom type class.
Comments
Post a Comment