未找到 LabelledGeneric 的无形映射器
shapeless Mapper for LabelledGeneric not found
我有这样定义的基本类型池:
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
我想介绍一些案例 类 由该池中的类型组成,如下所示:
final case class ContractViewPartners(customer: Customer, supplier: Supplier)
final case class ContractView(header: Header, partners: ContractViewPartners, tech: Tech)
由于它们将大量用于通过使用 here 描述的方法转换为 HList
s 实现的特征生成器,我想确保呈现类型的每个字段都是
Section
亚型
HList
个 Section
个子类型
- 记录显示为
Section
个子类型的 HList
我已经为这种情况定义了简单的编译时检查器:
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
}
但是它失败了(删除了包名)
could not find implicit value for parameter mapper:
Mapper[traverseView.type,::[Header with KeyTag[Symbol with
Tagged[String("header")],Header],::[ContractViewPartners with
KeyTag[Symbol with
Tagged[String("partners")],ContractViewPartners],::[Tech with
KeyTag[Symbol with Tagged[String("tech")],Tech],HNil]]]]
如果我从 ContractView
中删除 partners
部分,它会起作用,如果我尝试在 ContractViewPartners
上解析 implicits
,它们也会被发现。
再次写问题时,我找到了添加 .values
的解决方案
private def contractViewIsMultiSection(v: ContractView) = {
val gen = LabelledGeneric[ContractView].to(v)
.values //!!!
gen map traverseView
}
会不会是类型 with KeyTag[...]
作为 LabelledGeneric
转换的源无法正常工作?
问题在于 Case
是不变的,因此您拥有 ContractViewPartners
的 Case
实例这一事实并不意味着您拥有 [=13] 的案例实例=] 带有类型级标签(它只是 ContractViewPartners
的子类型)。您可以通过为例如生成实例来非常直接地解决这个问题。 FieldType[K, ContractViewPartners]
(对于某些任意 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
}
如果您不关心标签,您也可以在 contractViewIsMultiSection
中使用 Generic[ContractView]
。
不过,我可能会建议不要对这种事情使用 Poly1
。如果你只是想证明类型是正确的,你可以使用自定义类型 class.
我有这样定义的基本类型池:
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
我想介绍一些案例 类 由该池中的类型组成,如下所示:
final case class ContractViewPartners(customer: Customer, supplier: Supplier)
final case class ContractView(header: Header, partners: ContractViewPartners, tech: Tech)
由于它们将大量用于通过使用 here 描述的方法转换为 HList
s 实现的特征生成器,我想确保呈现类型的每个字段都是
Section
亚型HList
个Section
个子类型- 记录显示为
Section
个子类型的HList
我已经为这种情况定义了简单的编译时检查器:
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
}
但是它失败了(删除了包名)
could not find implicit value for parameter mapper: Mapper[traverseView.type,::[Header with KeyTag[Symbol with Tagged[String("header")],Header],::[ContractViewPartners with KeyTag[Symbol with Tagged[String("partners")],ContractViewPartners],::[Tech with KeyTag[Symbol with Tagged[String("tech")],Tech],HNil]]]]
如果我从 ContractView
中删除 partners
部分,它会起作用,如果我尝试在 ContractViewPartners
上解析 implicits
,它们也会被发现。
再次写问题时,我找到了添加 .values
的解决方案
private def contractViewIsMultiSection(v: ContractView) = {
val gen = LabelledGeneric[ContractView].to(v)
.values //!!!
gen map traverseView
}
会不会是类型 with KeyTag[...]
作为 LabelledGeneric
转换的源无法正常工作?
问题在于 Case
是不变的,因此您拥有 ContractViewPartners
的 Case
实例这一事实并不意味着您拥有 [=13] 的案例实例=] 带有类型级标签(它只是 ContractViewPartners
的子类型)。您可以通过为例如生成实例来非常直接地解决这个问题。 FieldType[K, ContractViewPartners]
(对于某些任意 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
}
如果您不关心标签,您也可以在 contractViewIsMultiSection
中使用 Generic[ContractView]
。
不过,我可能会建议不要对这种事情使用 Poly1
。如果你只是想证明类型是正确的,你可以使用自定义类型 class.