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 hlists using method described here, i'd ensure each field of presented type 1 of
sectionsubtypehlistofsectionsubtypes- record presentable
hlistofsectionsubtypes
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