次のコードでは、シェイプレスでtypeclassインスタンスを導出しようとしています。しかし、より複雑なケースクラス(より複雑なHListに変換される)の場合、同じ種類の暗黙の型を2度解決しないように見えますが、コンパイラは私に "多様な暗黙の拡張"を与えます。たぶん私はコンパイラのいくつかの他のルールが欠けているでしょうか?スカラックはなぜここに「多様な暗黙的な拡張」エラーを起こすのですか?
(フィドル: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フィールドのケースクラスでは、コンパイラはこのようなことをすることができません - なぜ私はそれを動作させるためにここでLazy
を使用する必要がありますか?
TC[Trait2]
Generic[Trait2]
TC[ComplexClass :+: CNil]
TC[ComplexClass]
Generic[ComplexClass]
TC[String :: String :: HNil]
TC[CNil]
私はそこでコードを実行できるようにいくつかのフィドルを作成しました。
私はその質問の鉱山とまったく同じではありませんが、マイルの答え[ここ](http://stackoverflow.com/a/27911353/334519)は説明です。 –