Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flavour of meta-programming with Shapeless

Flavour of meta-programming with Shapeless

Avatar for Arthur Kushka

Arthur Kushka

March 30, 2017
Tweet

More Decks by Arthur Kushka

Other Decks in Programming

Transcript

  1. ...lets imagine that your program its just a data. Meta

    programming is about: META F L A V O U R O F M - P R O G R A M M I N G W I T H S H A P E L E S S flatMap Exposing part of compiler outside Code generation Moving to compile time evaluation
  2. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it How we can store different types of data in one data structure?
  3. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it List[Any] List[AbstractClass] HList
  4. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it HList - its infinite static typed list based on abstract data types. Its like tuple: (String, Int, Long, ...), but without limit on amount of elements inside.
  5. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it HList example: val list: String :: Int :: HNil = "Word" :: 99 :: HNil
  6. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it What we can do with String :: Int :: HNil type Everything! def transform(hList: HList.Repr): Seq[String]
  7. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it String :: Int :: HNil HList[String, HList[Int, HNil]] and we want achieve Seq[String] Basic types transformers: Int => Seq[String] Shapeless type transformer: HList[A, B] => Seq[String]
  8. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it trait Transformer[A] { def transform(a: A): Seq[String] } implicit val intT = new Transformer[Int] { def transform(a: Int): Seq[String] = Seq(a.toString) }
  9. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it // HList[String, HList[Int, HNil]] implicit def hListT[H, T <: HList] (implicit headT: Transformer[H], tailT: Transformer[T]): Transformer[H :: T] = ??? implicit val hNilT = new Transformer[HNil] { override def transform(a: HNil): Seq[String] = Nil }
  10. SHAPELESS F L A V O U R O F

    M - P R O G R A M M I N G W I T H S H A P E L E S S Library that implements heterogeneous list and bunch of macroses for it implicitly[Transformer[String :: Int :: Nil]].transform(ourHList) Search for implicit to convert HList[A, B] Build HList[String, HList[B, C]] Search for implicit to convert String Search for implicit to convert Int and Nil Provide converter from HList[Int, Nil] to Seq[String] Provide converter from HList[String, HList[Int, Nil]] to Seq!
  11. USE CASE F L A V O U R O

    F M - P R O G R A M M I N G W I T H S H A P E L E S S case class User ( name: String, age: Int ) User("MyName", 99) def serialize(user: User): String = ??? // "MyName, 99"
  12. USE CASE F L A V O U R O

    F M - P R O G R A M M I N G W I T H S H A P E L E S S implicit val customerGen = Generic[Customer] def createEncoder[A, R] (implicit gen: Generic.Aux[A, R], encoder: Transformer[R]): Transformer[A] = new Transformer[A] { override def transform(a: A) = encoder.encode(gen.to(a)) }