Scala 在标记的case类上生成LabelledGeneric实例会在shapeless中产生一个错误

Scala 在标记的case类上生成LabelledGeneric实例会在shapeless中产生一个错误,scala,generic-programming,shapeless,Scala,Generic Programming,Shapeless,我试图从另一个HList(确切地说是另一个LabelledGeneric)的标记类型中获取一个LabelledGeneric实例,但是编译器产生了一个错误,说它找不到隐式类型 确切的错误是(启用-x-log-implicits): 以下是代码片段: case class Inner(a: Int) case class Outer(b: Int, c: Inner) val gen = LabelledGeneric[Outer] val inner = Inner(1) val outer

我试图从另一个HList(确切地说是另一个LabelledGeneric)的标记类型中获取一个LabelledGeneric实例,但是编译器产生了一个错误,说它找不到隐式类型

确切的错误是(启用-x-log-implicits):

以下是代码片段:

case class Inner(a: Int)
case class Outer(b: Int, c: Inner)

val gen = LabelledGeneric[Outer]

val inner = Inner(1)
val outer = Outer(2, inner)

def getGen[A, L](x: A)(implicit gen: LabelledGeneric.Aux[A, L]) = gen

val hOuter = gen.to(outer)

getGen(hOuter.at(1))
我是不是漏掉了什么明显的东西

谢谢

编辑:


我添加了case类的定义。我也在使用scala 2.11.8和shapeless 2.3.0

LabelledGeneric[Outer]
Outer
类型的值记录到无形状的记录上。这些是
HList
s字段,每个字段都是一个用“标签”标记的值。。。与case类中字段名称相对应的单例类型。类型
T
的标签值是类型
T
的子类型,但这两种类型不同。通常这是绝对好的

在您的场景中,您使用的是
hOuter.at(1)
字段,其类型为
FieldType['c.type,Inner]
。这是一个类型别名,扩展为以下内容:

Inner with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("c")],Inner]
然后请求与该类型对应的
LabelledGeneric
实例。不幸的是,
internal
有一个
LabelledGeneric
实例,而
FieldType['c.type,internal]
没有实例,因为正如编译器错误消息所说(wrt扩展类型)

如果您实际上没有将标签用于任何事情,那么最简单的解决方法是在整个过程中或至少在
gen
的定义中使用
Generic
而不是
LabelledGeneric

如果您正在使用标签,那么解决问题的方法是将它们从字段中剥离。最简单的方法是依赖
internal
作为
FieldType['c.type,internal]
的子类型,并使用类型归属

getGen(hOuter.at(1): Inner)
这意味着
getGen
的类型参数
A
将被推断为
internal
,并且
LabelledGeneric[A]
的隐式查找将成功


一个更通用的解决方案是使用shapeless的
Values
类型类,该类获取一个shapeless记录并从每个元素上剥离标签,从而生成一个仅由值组成的
HList

您能否包括
外部
内部
的定义,并说明shapess和
的版本和你一起工作的scalac。我已经把它们添加到问题中了
Inner with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("c")],Inner]
is not case class like or the root of a sealed family of types
getGen(hOuter.at(1): Inner)