shapeless 中的联积无法编译

Coproducts in shapeless does not compile

我正在试验 shapeless,现在正试图了解 Generic 的联积。这是我尝试过的:

object ShapelessExperiments {
    final case class Test1()
    final case class Test2()
    final case class Test3()

    type Test = Test1 :+: Test2 :+: Test3 :+: CNil

    val t1: Test = Inr(Inl(Test2()))  //fine
    val t2: Test = Generic[Test].to(Test2())  //compile error
}

我希望 val t2val t1 完全相同,但不幸的是它甚至无法编译:

Error:(13, 25) could not find implicit value for parameter gen: shapeless.Generic[com.test.ShapelessExperiments.Test]
  val t2: Test = Generic[Test].to(Test2())

Error:(13, 25) not enough arguments for method apply: (implicit gen: shapeless.Generic[com.test.ShapelessExperiments.Test])shapeless.Generic.Aux[com.test.ShapelessExperiments.Test,gen.Repr] in object Generic.
Unspecified value parameter gen.
  val t2: Test = Generic[Test].to(Test2())

这个错误对我来说不是很清楚也没有帮助。你能解释一下最后一个案例出了什么问题吗?

我想你在找 Inject:

import shapeless._
import shapeless.ops.coproduct.Inject // for converter object
import shapeless.syntax.inject._ // for nice syntax

object ShapelessExperiments extends App {
    final case class Test1()
    final case class Test2()
    final case class Test3()

    type Test = Test1 :+: Test2 :+: Test3 :+: CNil

    val t1: Test = Inr(Inl(Test2()))  //fine
    val t2: Test = Inject[Test, Test2].apply(Test2())
    val t3: Test = Test2().inject[Test]
    println(t1 == t2) // true
    println(t1 == t3) // true 
}

Generic[A] 目的不同:它说 A 是同构的(可以来回转换,没有任何数据丢失)到某种类型 B,其中 B通常是一个HList(如果A是一个案例class)或一个Coproduct(如果A是一个密封的特征)。

AHListCoproduct 本身时,这些实例不可用 (source)