Skip to content

Instantly share code, notes, and snippets.

@LeifW
Last active January 10, 2019 10:28
Show Gist options
  • Save LeifW/4bcdf122883dd5354d45ced6a88a8235 to your computer and use it in GitHub Desktop.
Save LeifW/4bcdf122883dd5354d45ced6a88a8235 to your computer and use it in GitHub Desktop.
Shapeless generic decode
import shapeless._
import shapeless.labelled.{FieldType, field}
abstract class Decode[A] {
def get: A
}
object Decode {
def apply[A](implicit decoder: Decode[A]) = decoder
implicit object getString extends Decode[String] { val get = "A string" }
implicit object getInt extends Decode[Int] { val get = 66 }
implicit object decodeHNil extends Decode[HNil] { val get = HNil }
implicit def decodeHCons[
K <: Symbol,
V,
T <: HList
](implicit
key: Witness.Aux[K],
decodeV: Decode[V],
decodeT: Decode[T]): Decode[FieldType[K, V] :: T] = new Decode[FieldType[K, V] :: T] {
val get = field[K](decodeV.get) :: decodeT.get
}
implicit def decodeGeneric[T, Repr](implicit
gen: LabelledGeneric.Aux[T, Repr],
decodeRepr: Decode[Repr]
): Decode[T] = new Decode[T] {
def get = gen.from(decodeRepr.get)
}
}
import shapeless._
trait Decode[A] {
def get: A
}
object Decode extends LabelledProductTypeClassCompanion[Decode] {
implicit object getString extends Decode[String] { val get = "A string" }
implicit object getInt extends Decode[Int] { val get = 66 }
object typeClass extends LabelledProductTypeClass[Decode] {
val emptyProduct: Decode[HNil] = new Decode[HNil]{ val get = HNil }
def product[H, T <: HList](name: String, ch: Decode[H], ct: Decode[T]) = new Decode[H :: T] {
val get = ch.get :: ct.get
}
def project[F, G](instance: => Decode[G], to: F => G, from: G => F) = new Decode[F] {
val get = from(instance.get)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment