Last active
January 10, 2019 10:28
-
-
Save LeifW/4bcdf122883dd5354d45ced6a88a8235 to your computer and use it in GitHub Desktop.
Shapeless generic decode
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
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) | |
} | |
} |
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
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