Last active
June 6, 2017 09:44
-
-
Save BenFradet/e1274641d527aa144da9addebaa70478 to your computer and use it in GitHub Desktop.
Ambiguous implicits
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract class DT | |
case object NullT extends DT | |
case object IntegerT extends DT | |
case object StringT extends DT | |
case class ST(fields: List[(String, DT)]) extends DT | |
sealed trait DTEncoder[A] { | |
def encode: DT | |
} | |
sealed trait STEncoder[A] extends DTEncoder[A] { | |
def encode: ST | |
} | |
object STEncoder { | |
def apply[A](implicit enc: STEncoder[A]): STEncoder[A] = enc | |
def pureST[A](st: ST): STEncoder[A] = | |
new STEncoder[A] { def encode: ST = st } | |
def pureDT[A](dt: DT): DTEncoder[A] = | |
new DTEncoder[A] { def encode: DT = dt } | |
implicit val nullEncoder: DTEncoder[Unit] = pureDT(NullT) | |
implicit val intEncoder: DTEncoder[Int] = pureDT(IntegerT) | |
implicit val stringEncoder: DTEncoder[String] = pureDT(StringT) | |
implicit val hnilEncoder: STEncoder[HNil] = pureST(ST(Nil)) | |
implicit def hconsEncoder[K <: Symbol, H, T <: HList]( | |
implicit | |
witness: Witness.Aux[K], | |
hEncoder: Lazy[DTEncoder[H]], | |
tEncoder: STEncoder[T] | |
): STEncoder[FieldType[K, H] :: T] = { | |
val fieldName = witness.value.name | |
pureST { | |
val head = hEncoder.value.encode | |
val tail = tEncoder.encode | |
ST((fieldName, head) +: tail.fields) | |
} | |
} | |
implicit def genericEncoder[A, H <: HList]( | |
implicit | |
generic: LabelledGeneric.Aux[A, H], | |
hEncoder: Lazy[STEncoder[H]] | |
): STEncoder[A] = | |
pureST(hEncoder.value.encode) | |
} | |
case class Foo(a: Unit) | |
STEncoder[Foo].encode | |
// [error] both value nullEncoder in object STEncoder of type => DTEncoder[Unit] | |
// [error] and method genericEncoder in object STEncoder of type [A, H <: shapeless.HList](implicit generic: shapeless.LabelledGeneric.Aux[A,H], implicit hEncoder: shapeless.Lazy[STEncoder[H]])STEncoder[A] | |
// [error] match expected type ste.DTEncoder[Unit] | |
// [error] STEncoder[A].encode shouldBe ST(("a", NullType) :: Nil) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment