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

Flavour of meta-programming with Shapeless

Flavour of meta-programming with Shapeless

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)) }