Introduction to Type Driven Development in Scala Marcus






![trait My. Trait[A, B]{type Out} object My. Trait{ def apply[A, B, C](): My. Trait[A, trait My. Trait[A, B]{type Out} object My. Trait{ def apply[A, B, C](): My. Trait[A,](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-7.jpg)
![trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My.](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-8.jpg)
![trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My.](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-9.jpg)
![trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My.](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-10.jpg)
![trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My.](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-11.jpg)
![trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My.](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-12.jpg)
![trait Mapping[A, B]{ def map(a: A): B } @dreadedsoftware | @integrichain trait Mapping[A, B]{ def map(a: A): B } @dreadedsoftware | @integrichain](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-13.jpg)
![val mapping: Mapping[List[Int], List[String]] = new Mapping[List[Int], List[String]]{ override def map(a: List[Int]): List[String] = val mapping: Mapping[List[Int], List[String]] = new Mapping[List[Int], List[String]]{ override def map(a: List[Int]): List[String] =](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-14.jpg)
![trait List. Mapping[A, B]{ def map(list: List[A])(f: A => B): List[B] = list. map(f) trait List. Mapping[A, B]{ def map(list: List[A])(f: A => B): List[B] = list. map(f)](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-15.jpg)
(f: A => B): List[B] = list. map(f) trait List. Mapping{ def map[A, B](list: List[A])(f: A => B): List[B] = list. map(f)](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-16.jpg)
(f: A => object List. Reverse. Mapping extends List. Mapping{ override def map[A, B](list: List[A])(f: A =>](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-17.jpg)
![trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware |](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-18.jpg)
![trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware |](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-19.jpg)
![trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware |](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-20.jpg)
![trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware |](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-21.jpg)
![trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware |](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-22.jpg)
![implicit val list. With. Map = new With. Map[List]{ override def map[A, B](m: List[A])(f: implicit val list. With. Map = new With. Map[List]{ override def map[A, B](m: List[A])(f:](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-23.jpg)
![def pretty. String[ F[_]: With. Map, A](m: F[A])(f: A => String): String = { def pretty. String[ F[_]: With. Map, A](m: F[A])(f: A => String): String = {](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-24.jpg)
![def process. Data[F[_]: With. Map, A, B, C, D](m 1: F[A])( f 1: A def process. Data[F[_]: With. Map, A, B, C, D](m 1: F[A])( f 1: A](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-25.jpg)




![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-30.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-31.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-32.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-33.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-34.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-35.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-36.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-37.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-38.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-39.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-40.jpg)
![https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-41.jpg)
: List[(A, (B, C))] def zipper[A, B, C]( a: List[A], b: List[B], c: List[C] ): List[(A, (B, C))]](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-42.jpg)
![trait Zip[F[_]]{ def apply[A, B](a: F[A], b: F[B]): F[(A, B)] } @dreadedsoftware | @integrichain trait Zip[F[_]]{ def apply[A, B](a: F[A], b: F[B]): F[(A, B)] } @dreadedsoftware | @integrichain](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-43.jpg)
![def zipper[F[_]: Zip, A, B, C]( a: F[A], b: F[B], c: F[C]): F[(A, (B, def zipper[F[_]: Zip, A, B, C]( a: F[A], b: F[B], c: F[C]): F[(A, (B,](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-44.jpg)
![def zipper[F[_]: Zip, H, T]( h: F[H], t: F[T]): F[(H, T)] = { val def zipper[F[_]: Zip, H, T]( h: F[H], t: F[T]): F[(H, T)] = { val](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-45.jpg)
![implicit val Zip. List = new Zip[List]{ override def apply[A, B]( a: List[A], b: implicit val Zip. List = new Zip[List]{ override def apply[A, B]( a: List[A], b:](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-46.jpg)
![implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = { implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = {](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-47.jpg)
![implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = { implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = {](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-48.jpg)
![implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = { implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = {](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-49.jpg)
![type F[A] = List[A] type Result = F[ (Int, (Long, (String, (Double, (Float, Array[Byte]) type F[A] = List[A] type Result = F[ (Int, (Long, (String, (Double, (Float, Array[Byte])](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-50.jpg)
![trait Zip. G[F[_], G[_, _]]{ def apply[A, B](a: F[A], b: F[B]): F[G[A, B]] } trait Zip. G[F[_], G[_, _]]{ def apply[A, B](a: F[A], b: F[B]): F[G[A, B]] }](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-51.jpg)

![type F[A] = List[A] type Result = F[ (Int, (Long, (String, (Double, (Float, Array[Byte]) type F[A] = List[A] type Result = F[ (Int, (Long, (String, (Double, (Float, Array[Byte])](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-53.jpg)
![type F[A] = List[A] type Result = F[ Either[Int, Either[Long, Either[String, Either[Double, Either[Float, Array[Byte]] type F[A] = List[A] type Result = F[ Either[Int, Either[Long, Either[String, Either[Double, Either[Float, Array[Byte]]](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-54.jpg)

![import cats. Functor val functor. List = new Functor[List]{ override def map[A, B](fa: List[A])(f: import cats. Functor val functor. List = new Functor[List]{ override def map[A, B](fa: List[A])(f:](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-56.jpg)
![import cats. Show def stringify 3[F[_]: Functor, A, B, C]( fa: A => String, import cats. Show def stringify 3[F[_]: Functor, A, B, C]( fa: A => String,](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-57.jpg)
![def stringify 4[F[_]: Functor, A: Show, B: Show, C: Show]( in: F[(A, (B, C))])(implicit def stringify 4[F[_]: Functor, A: Show, B: Show, C: Show]( in: F[(A, (B, C))])(implicit](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-58.jpg)
![def stringify 5[F[_]: Functor, A: Show, B: Show]( in: F[(A, B)])(implicit FS: Show[F[String]]): String def stringify 5[F[_]: Functor, A: Show, B: Show]( in: F[(A, B)])(implicit FS: Show[F[String]]): String](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-59.jpg)
![implicit def make. Show[A: Show, B: Show]: Show[(A, B)] = { val fa = implicit def make. Show[A: Show, B: Show]: Show[(A, B)] = { val fa =](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-60.jpg)
![def stringify[F[_]: Functor, A: Show]( in: F[A])(implicit FS: Show[F[String]]): String = { val F def stringify[F[_]: Functor, A: Show]( in: F[A])(implicit FS: Show[F[String]]): String = { val F](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-61.jpg)
![implicit val Show. List. String = new Show[List[String]]{ def show(in: List[String]): String = in. implicit val Show. List. String = new Show[List[String]]{ def show(in: List[String]): String = in.](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-62.jpg)
![//Write thing with our writer val result = implicitly[Result 1] //Read the thing back //Write thing with our writer val result = implicitly[Result 1] //Read the thing back](https://slidetodoc.com/presentation_image/339489f51cbe49024344e8b631b2f336/image-63.jpg)

- Slides: 64
Introduction to Type Driven Development in Scala Marcus A. Henry, Jr. @dreadedsoftware Software Engineer @integrichain @dreadedsoftware | @integrichain
def f(a: Int, b: Int): String = { a. to. String + b. to. String } @dreadedsoftware | @integrichain
def f(a: Int, b: Int): String = { a. to. String + b. to. String } @dreadedsoftware | @integrichain
def f(a: Int, b: Int): String = { a. to. String + b. to. String } @dreadedsoftware | @integrichain
def f(a: Int, b: Int): String = { a. to. String + b. to. String } @dreadedsoftware | @integrichain
def f(a: Int, b: Int): String = { a. to. String + b. to. String } @dreadedsoftware | @integrichain
trait My. Trait[A, B]{type Out} object My. Trait{ def apply[A, B, C](): My. Trait[A, B]{type Out = C} = new My. Trait[A, B]{override type Out = C} } @dreadedsoftware | @integrichain
trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. Trait[A, B]{type Out = C} def apply[A, B, C](): Aux[A, B, C] = new My. Trait[A, B]{override type Out = C} } @dreadedsoftware | @integrichain
trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. Trait[A, B]{type Out = C} def apply[A, B, C](): Aux[A, B, C] = new My. Trait[A, B]{override type Out = C} } @dreadedsoftware | @integrichain
trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. Trait[A, B]{type Out = C} def apply[A, B, C](): Aux[A, B, C] = new My. Trait[A, B]{override type Out = C} } @dreadedsoftware | @integrichain
trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. Trait[A, B]{type Out = C} def apply[A, B, C](): Aux[A, B, C] = new My. Trait[A, B]{override type Out = C} } @dreadedsoftware | @integrichain
trait My. Trait[A, B]{type Out} object My. Trait{ type Aux[A, B, C] = My. Trait[A, B]{type Out = C} def apply[A, B, C](): Aux[A, B, C] = new My. Trait[A, B]{override type Out = C} } @dreadedsoftware | @integrichain
trait Mapping[A, B]{ def map(a: A): B } @dreadedsoftware | @integrichain
val mapping: Mapping[List[Int], List[String]] = new Mapping[List[Int], List[String]]{ override def map(a: List[Int]): List[String] = a. map(_. to. String) } @dreadedsoftware | @integrichain
trait List. Mapping[A, B]{ def map(list: List[A])(f: A => B): List[B] = list. map(f) } @dreadedsoftware | @integrichain
trait List. Mapping{ def map[A, B](list: List[A])(f: A => B): List[B] = list. map(f) } @dreadedsoftware | @integrichain
object List. Reverse. Mapping extends List. Mapping{ override def map[A, B](list: List[A])(f: A => B): List[B] = list. reverse. map(f) } @dreadedsoftware | @integrichain
trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | @integrichain
trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | @integrichain
trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | @integrichain
trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | @integrichain
trait With. Map[F[_]]{ def map[A, B](m: F[A])(f: A => B): F[B] } @dreadedsoftware | @integrichain
implicit val list. With. Map = new With. Map[List]{ override def map[A, B](m: List[A])(f: A => B): List[B] = m. map(f) } implicit val option. With. Map = new With. Map[Option]{ override def map[A, B](m: Option[A])(f: A => B): Option[B] = m. map(f) } implicit val stream. With. Map = new With. Map[Stream]{ override def map[A, B](m: Stream[A])(f: A => B): Stream[B] = m. map(f) } val reverse. List. With. Map = new With. Map[List]{ override def map[A, B](m: List[A])(f: A => B): List[B] = m. reverse. map(f) } @dreadedsoftware | @integrichain
def pretty. String[ F[_]: With. Map, A](m: F[A])(f: A => String): String = { implicitly[With. Map[F]]. map(m)(f). to. String } val list = List(rnd, rnd) val stream = Stream(rnd, rnd) val option = Option(rnd) val f 1: Int => String = {i: Int => "As String: " + i. to. String } pretty. String(list)(f 1) pretty. String(option)(f 1) pretty. String(stream)(f 1) @dreadedsoftware | @integrichain
def process. Data[F[_]: With. Map, A, B, C, D](m 1: F[A])( f 1: A => B)( f 2: B => C)( f 3: C => D): F[D] = { val F = implicitly[With. Map[F]] val m 2 = F. map(m 1)(f 1) val m 3 = F. map(m 2)(f 2) F. map(m 3)(f 3) } val f 2: String => Array[Byte] = _. get. Bytes val f 3: Array[Byte] => Long = _. map(_. to. Long). sum process. Data(list)(f 1)(f 2)(f 3) process. Data(option)(f 1)(f 2)(f 3) process. Data(stream)(f 1)(f 2)(f 3) @dreadedsoftware | @integrichain
Some Type Some Function @dreadedsoftware | @integrichain
Some Function Some Typeclass Instance @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/hlists. scala sealed trait HList extends Product with Serializable final case class : : [+H, override def to. String case _: : : [_, _] => case _ => head+" : : } } +T <: HList](head : H, tail : T) extends HList { = head match { "("+head+") : : "+tail. to. String sealed trait HNil extends HList { def : : [H](h : H) = shapeless. : : (h, this) override def to. String = "HNil" } case object HNil extends HNil @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/hlists. scala sealed trait HList extends Product with Serializable final case class : : [+H, override def to. String case _: : : [_, _] => case _ => head+" : : } } +T <: HList](head : H, tail : T) extends HList { = head match { "("+head+") : : "+tail. to. String sealed trait HNil extends HList { def : : [H](h : H) = shapeless. : : (h, this) override def to. String = "HNil" } case object HNil extends HNil @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
https: //github. com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/hlists. scala#L 62 trait Mapped[L <: HList, F[_]] extends Serializable { type Out <: HList } object Mapped { … type Aux[L <: HList, F[_], Out 0 <: HList] = Mapped[L, F] { type Out = Out 0 } implicit def hnil. Mapped[F[_]]: Aux[HNil, F, HNil] = new Mapped[HNil, F] { type Out = HNil } … implicit def hlist. Mapped 1[ H, T <: HList, F[_], Out. M <: HList](implicit mt: Mapped. Aux[T, F, Out. M]): Aux[H : : T, F, F[H] : : Out. M] = new Mapped[H : : T, F] { type Out = F[H] : : Out. M } } @dreadedsoftware | @integrichain
def zipper[A, B, C]( a: List[A], b: List[B], c: List[C] ): List[(A, (B, C))] = a. zip(b. zip(c)) @dreadedsoftware | @integrichain
trait Zip[F[_]]{ def apply[A, B](a: F[A], b: F[B]): F[(A, B)] } @dreadedsoftware | @integrichain
def zipper[F[_]: Zip, A, B, C]( a: F[A], b: F[B], c: F[C]): F[(A, (B, C))] = { val F = implicitly[Zip[F]] F(a, F(b, c)) } @dreadedsoftware | @integrichain
def zipper[F[_]: Zip, H, T]( h: F[H], t: F[T]): F[(H, T)] = { val F = implicitly[Zip[F]] F(h, t) } @dreadedsoftware | @integrichain
implicit val Zip. List = new Zip[List]{ override def apply[A, B]( a: List[A], b: List[B]): List[(A, B)] = a. zip(b) } val with 2 = zipper(list 1, list 2) val with 3 = zipper(list 1, zipper(list 2, list 3)) val with 6 = zipper(list 1, zipper(list 2, zipper(list 3, zipper(list 4, zipper(list 5, list 6))))) @dreadedsoftware | @integrichain
implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = { val F = implicitly[Zip[F]] F(h, t) } @dreadedsoftware | @integrichain
implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = { val F = implicitly[Zip[F]] F(h, t) } @dreadedsoftware | @integrichain
implicit def zipper[F[_]: Zip, H, T](implicit h: F[H], t: F[T]): F[(H, T)] = { val F = implicitly[Zip[F]] F(h, t) } @dreadedsoftware | @integrichain
type F[A] = List[A] type Result = F[ (Int, (Long, (String, (Double, (Float, Array[Byte]) ))))] implicit implicit val val val list 1: list 2: list 3: list 4: list 5: list 6: List[Int] = ? ? ? List[Long] = ? ? ? List[String] = ? ? ? List[Double] = ? ? ? List[Float] = ? ? ? List[Array[Byte]] = ? ? ? implicitly[Result] @dreadedsoftware | @integrichain
trait Zip. G[F[_], G[_, _]]{ def apply[A, B](a: F[A], b: F[B]): F[G[A, B]] } implicit def zipper[F[_], G[_, _], H, T](implicit F: Zip. G[F, G], h: F[H], t: F[T]): F[G[H, T]] = { F(h, t) } implicit val zip. List. Tuple 2 = new Zip. G[List, Tuple 2]{ override def apply[A, B]( a: List[A], b: List[B]): List[(A, B)] = a. zip(b) } @dreadedsoftware | @integrichain
implicit val zip. List. Tuple 2 = new Zip. G[List, override def apply[A, B]( a: List[A], b: List[B]): List[(A, B)] = } implicit val zip. List. Either = new Zip. G[List, override def apply[A, B]( a: List[A], b: List[B]): List[Either[A, for{a <- a; b <- b}yield{ if(a. to. String. size < b. to. String. size) else Right(b) } } @dreadedsoftware | @integrichain Tuple 2]{ a. zip(b) Either]{ B]] = Left(a)
type F[A] = List[A] type Result = F[ (Int, (Long, (String, (Double, (Float, Array[Byte]) ))))] implicit implicit val val val list 1: list 2: list 3: list 4: list 5: list 6: List[Int] = ? ? ? List[Long] = ? ? ? List[String] = ? ? ? List[Double] = ? ? ? List[Float] = ? ? ? List[Array[Byte]] = ? ? ? implicitly[Result] @dreadedsoftware | @integrichain
type F[A] = List[A] type Result = F[ Either[Int, Either[Long, Either[String, Either[Double, Either[Float, Array[Byte]] ]]]]] implicit implicit val val val list 1: list 2: list 3: list 4: list 5: list 6: List[Int] = ? ? ? List[Long] = ? ? ? List[String] = ? ? ? List[Double] = ? ? ? List[Float] = ? ? ? List[Array[Byte]] = ? ? ? implicitly[Result] @dreadedsoftware | @integrichain
def stringify 1[A, B, C]( fa: A => String, fb: B => String, fc: C => String, in: List[(A, (B, C))]): String = { in. map{case (a, (b, c)) => fa(a) + ", " + fb(b) + ", " + fc(c) }. mk. String("(", "; ", ")") } @dreadedsoftware | @integrichain
import cats. Functor val functor. List = new Functor[List]{ override def map[A, B](fa: List[A])(f: A => B): F[B] = fa. map(f) } def stringify 2[F[_]: Functor, A, B, C]( fa: A => String, fb: B => String, fc: C => String, in: F[(A, (B, C))]): String = { val F = implicitly[Functor[F]] F. map(in){case (a, (b, c)) => fa(a) + ", " + fb(b) + ", " + fc(c) } ? ? ? } @dreadedsoftware | @integrichain
import cats. Show def stringify 3[F[_]: Functor, A, B, C]( fa: A => String, fb: B => String, fc: C => String, in: F[(A, (B, C))])(implicit FS: Show[F[String]]): String = { val F = implicitly[Functor[F]] val result = F. map(in){case (a, (b, c)) => fa(a) + ", " + fb(b) + ", " + fc(c) } FS. show(result) } @dreadedsoftware | @integrichain
def stringify 4[F[_]: Functor, A: Show, B: Show, C: Show]( in: F[(A, (B, C))])(implicit FS: Show[F[String]]): String = { val F = implicitly[Functor[F]] val fa = implicitly[Show[A]]. show _ val fb = implicitly[Show[B]]. show _ val fc = implicitly[Show[C]]. show _ val result = F. map(in){case (a, (b, c)) => fa(a) + ", " + fb(b) + ", " + fc(c) } FS. show(result) } @dreadedsoftware | @integrichain
def stringify 5[F[_]: Functor, A: Show, B: Show]( in: F[(A, B)])(implicit FS: Show[F[String]]): String = { val F = implicitly[Functor[F]] val fa = implicitly[Show[A]]. show _ val fb = implicitly[Show[B]]. show _ val result = F. map(in){case (a, b) => fa(a) + ", " + fb(b) } FS. show(result) } @dreadedsoftware | @integrichain
implicit def make. Show[A: Show, B: Show]: Show[(A, B)] = { val fa = implicitly[Show[A]]. show _ val fb = implicitly[Show[B]]. show _ new Show[(A, B)]{ override def show(t: (A, B)): String = { val (a, b) = t "(" + fa(a) + ", " + fb(b) + ")“ } } } @dreadedsoftware | @integrichain
def stringify[F[_]: Functor, A: Show]( in: F[A])(implicit FS: Show[F[String]]): String = { val F = implicitly[Functor[F]] val fa = implicitly[Show[A]]. show _ val result = F. map(in)(fa) FS. show(result) } @dreadedsoftware | @integrichain
implicit val Show. List. String = new Show[List[String]]{ def show(in: List[String]): String = in. mk. String("(", "; ", ")") } implicit val show. Int = new Show[Int]{ override def show(in: Int): String = in. to. String} implicit val show. Long = new Show[Long]{ override def show(in: Long): String = in. to. String} implicit val show. String = new Show[String]{ override def show(in: String): String = in} implicit val show. Double = new Show[Double]{ override def show(in: Double): String = f"$in%. 2 f"} implicit val show. Float = new Show[Float]{ override def show(in: Float): String = f"$in%. 2 f"} implicit val show. Array. Byte = new Show[Array[Byte]]{ override def show(in: Array[Byte]): String = new String(in)} @dreadedsoftware | @integrichain
//Write thing with our writer val result = implicitly[Result 1] //Read the thing back with our reader println(stringify(result)) @dreadedsoftware | @integrichain
Questions? @dreadedsoftware @integrichain @dreadedsoftware | @integrichain