在下面的代碼中,我嘗試導出無形狀的類型實例。然而,對於更復雜的案例類(它被轉換爲更復雜的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)是解釋,儘管在這個問題上我的情況並不完全一樣。 –