Skip to content

Instantly share code, notes, and snippets.

@SystemFw
Created July 13, 2017 13:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SystemFw/3cdb482c2fe1bf9151fe8420aaf0d033 to your computer and use it in GitHub Desktop.
Save SystemFw/3cdb482c2fe1bf9151fe8420aaf0d033 to your computer and use it in GitHub Desktop.
Shapeless semiautomatic derivation
object Module {
import shapeless._
sealed trait Decode[A] {
def decode(s: String): Option[A]
}
object Decode {
def dummy[A]: Decode[A] = new Decode[A] {
def decode(s: String) = Option.empty[A]
}
def apply[A](implicit decoder: Decode[A]): Decode[A] =
decoder
implicit def strings: Decode[String] = dummy[String]
implicit def bools: Decode[Boolean] = dummy[Boolean]
implicit def ints: Decode[Int] = dummy[Int]
implicit def hnil: Decode[HNil] = dummy[HNil]
implicit def hcons[H: Decode, T <: HList: Decode]: Decode[H :: T] =
dummy[H :: T]
implicit def cnil: Decode[CNil] = dummy[CNil]
implicit def ccons[H: Decode, T <: Coproduct: Decode]: Decode[H :+: T] =
dummy[H :+: T]
implicit def generics[A, R](implicit gen: Generic.Aux[A, R],
decoder: Decode[R], opt: OptIn[A]): Decode[A] = Decode.dummy[A]
}
sealed trait OptIn[A]
object OptIn {
def instance[A]: OptIn[A] = new OptIn[A] {}
}
trait DeriveDecoder[F] {
implicit def optIn[A <: F] = OptIn.instance[A]
}
}
sealed trait A
case class B(s: String, i: Int) extends A
case class C(b: Boolean) extends A
object A extends Module.DeriveDecoder[A]
sealed trait A1
case class B1(s: String, i: Int) extends A1
case class C1(b: Boolean) extends A1
object Test {
import shapeless.test._
val a = Module.Decode[A]
val b = illTyped("Module.Decode[A1]")
// code compiles
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment