在下面的代码中,我尝试导出无形状的类型实例。然而,对于更复杂的案例类(它被转换为更复杂的HList),编译器给了我一个“发散的隐式扩展”,即使它似乎没有两次解决同一种隐式类型。也许我错过了编译器的其他规则?为什么scalac在这里出现“分歧的隐含扩展”错误?
(小提琴:https://scalafiddle.io/sf/WEpnAXN/0)
import shapeless._
trait TC[T]
sealed trait Trait1
case class SimpleClass(a: String) extends Trait1
sealed trait Trait2
case class ComplexClass(a: String, b: String) extends Trait2
object Serialization extends App {
//Instances for HList
implicit val hnilInstance: TC[HNil] = ???
implicit def hconsInstance[H, T <: HList] (implicit t: TC[T]): TC[H :: T] = ???
//Instances for CoProduct
implicit val cnilInstance: TC[CNil] = ???
implicit def cconsInstance[H, T <: Coproduct] (implicit h: TC[H], t: TC[T]): TC[H :+: T] = ???
//Instances for Generic, relying on HNil & HCons
implicit def genericInstance[T, H] (implicit g: Generic.Aux[T, H], t: TC[H]): TC[T] = ???
the[TC[SimpleClass :+: CNil]] //Works
the[TC[Trait1]] //Works
the[TC[ComplexClass :+: CNil]] //Works
the[TC[Trait2]] //Fails with diverging implicit expansion
}
当试图解决the[TC[Trait1]]
编译器应该做这样的事情:
TC[Trait1]
Generic[Trait1]
TC[SimpleClass :+: CNil]
TC[SimpleClass]
Generic[SimpleClass]
TC[String :: HNil]
TC[CNil]
这似乎工作。但是,对于2字段的case类,编译器无法做到这一点 - 所以我想知道:为什么我必须在这里使用Lazy
才能使它工作?
TC[Trait2]
Generic[Trait2]
TC[ComplexClass :+: CNil]
TC[ComplexClass]
Generic[ComplexClass]
TC[String :: String :: HNil]
TC[CNil]
我创造了一些小提琴这样你就可以执行的代码有directy。
我怀疑迈尔斯的答案[这里](http://stackoverflow.com/a/27911353/334519)是解释,尽管在这个问题上我的情况并不完全一样。 –