다음 코드에서는 셰이프가없는 typeclass 인스턴스를 파생하려고합니다. 그러나 더 복잡한 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-field case 클래스를 사용하면 컴파일러가 이와 같은 작업을 수행하지 못합니다. 따라서 궁금한 점이 있습니다. 이제는 Lazy
을 사용해야 만 왜 작동합니까?
TC[Trait2]
Generic[Trait2]
TC[ComplexClass :+: CNil]
TC[ComplexClass]
Generic[ComplexClass]
TC[String :: String :: HNil]
TC[CNil]
나는 거기에 코드를 실행할 수 있도록 약간의 바이올린을 만들었습니다.
나는이 질문에서 내 케이스와 정확히 같지는 않지만 마일즈의 대답이 (http://stackoverflow.com/a/27911353/334519)라고 생각합니다. –