Scala 通过LiftAll收集实例

Scala 通过LiftAll收集实例,scala,shapeless,Scala,Shapeless,我试图描述case类包含的类型 import shapeless._ import shapeless.ops.hlist.LiftAll trait Desc[T] { def description: String } case class Foo(f: Int) object Foo { implicit val description: Desc[Foo] = new Desc[Foo] { val description = "foo" } } case class So

我试图描述case类包含的类型

import shapeless._
import shapeless.ops.hlist.LiftAll

trait Desc[T] {
  def description: String
}

case class Foo(f: Int)
object Foo {
  implicit val description: Desc[Foo] = new Desc[Foo] { val description = "foo" }
}

case class SomeCaseClass(f: Foo)

val gen = Generic[SomeCaseClass]
val lifted = implicitly[LiftAll[Desc, gen.Repr]].instances.toList
给我

could not find implicit value for parameter toTraversableAux: shapeless.ops.hlist.ToTraversable.Aux[shapeless.ops.hlist.LiftAll[Playground.this.Desc,Playground.this.gen.Repr]#Out,List,Lub]
not enough arguments for method toList: (implicit toTraversableAux: shapeless.ops.hlist.ToTraversable.Aux[shapeless.ops.hlist.LiftAll[Playground.this.Desc,Playground.this.gen.Repr]#Out,List,Lub])toTraversableAux.Out.
Unspecified value parameter toTraversableAux.

Scastie here:

当您使用
隐式[LiftAll[Desc,gen.Repr]]
调用隐式实例时,
LiftAll
的依赖类型
Out
将丢失,因此编译器不知道将返回哪个类型

为了解决这个问题,Shapeless中的大多数类型类在其伴生对象中定义了一个
apply
方法,该方法保留了所有依赖类型信息。这就是为什么在调用
val gen=Generic[SomeCaseClass]
之后,您可以有意义地使用
gen.Repr
。然而,由于某种原因,
LiftAll.apply
。因此,您可以选择隐式地实现自己的
,或者因为您使用的是无形状的,所以使用它的
隐式地
应该是更好的

scala> def impl[T <: AnyRef](implicit ev: T): ev.type = ev
impl: [T <: AnyRef](implicit ev: T)ev.type

scala> impl[LiftAll[Desc, gen.Repr]].instances.toList
res1: List[Desc[Foo]] = List(Foo$$anon$1@40b3708a)

scala> the[LiftAll[Desc, gen.Repr]].instances.toList
res2: List[Desc[Foo]] = List(Foo$$anon$1@40b3708a)
scala> impl[LiftAll[Desc, gen.Repr]]
res3: LiftAll.Aux[Desc,Foo :: HNil,Desc[Foo] :: HNil] = shapeless.ops.hlist$LiftAll$$anon$206@384d060c

scala> implicitly[LiftAll[Desc, gen.Repr]]
res4: LiftAll[Desc,gen.Repr] = shapeless.ops.hlist$LiftAll$$anon$206@30787774