Slide 1

Slide 1 text

! My name is @folone https://github.com/folone/fby

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

→ 12 hours uploaded every minute → ~35k listening years every month → >135M tracks (including content from majors: Sony/Universal/ Warner) → ~180M monthly active users

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Slide 7

Slide 7 text

Type level programming in Scala !

Slide 8

Slide 8 text

sealed trait Bool { type &&[B <: Bool] <: Bool type ||[B <: Bool] <: Bool type IfElse[T, F] <: Any } trait True extends Bool { type &&[B <: Bool] = B type ||[B <: Bool] = True type IfElse[T, F] = T } trait False extends Bool { type &&[B <: Bool] = False type ||[B <: Bool] = B type IfElse[T, F] = F }

Slide 9

Slide 9 text

// false || true == true implicitly[False # `||` [True] =:= True] // if(true) String else Int implicitly[True # IfElse[String, Int] =:= String] /* if(true) { * if(false) Long else String * } else Int */ implicitly[True # IfElse[False # IfElse[Long, String], Int] =:= String]

Slide 10

Slide 10 text

Peano numbers!

Slide 11

Slide 11 text

trait Nat trait Z extends Nat trait Succ[A <: Nat] extends Nat

Slide 12

Slide 12 text

trait MinusOne[A <: Nat] { type Res <: Nat } object MinusOne { type Aux[A <: Nat, Res1 <: Nat] = MinusOne[A] { type Res = Res1 } implicit val baseCase: Aux[Z, Z] = new MinusOne[Z] { type Res = Z } implicit def inductiveCase[A <: Nat]: Aux[Succ[A], A] = new MinusOne[Succ[A]] { type Res = A } }

Slide 13

Slide 13 text

trait Plus[A <: Nat, B <: Nat] { type Res <: Nat } object Plus { type Aux[A <: Nat, B <: Nat, Res1 <: Nat] = Plus[A, B] { type Res = Res1 } implicit def baseCase[A <: Nat]: Aux[A, Z, A] = new Plus[A, Z] { type Res = A } implicit def inductiveCase[A <: Nat, B <: Nat, C <: Nat, D <: Nat] (implicit ev0: MinusOne.Aux[B, C], ev1: Plus.Aux[Succ[A], C, D]): Aux[A, B, D] = new Plus[A, B] { type Res = D } }

Slide 14

Slide 14 text

implicit def inductiveCase[A <: Nat, B <: Nat, C <: Nat, D <: Nat] (implicit ev0: MinusOne.Aux[B, C], ev1: Plus.Aux[Succ[A], C, D]): Aux[A, B, D] = new Plus[A, B] { type Res = D }

Slide 15

Slide 15 text

type _1 = Succ[Z] type _2 = Succ[_1] type _3 = Succ[_2] implicitly[Plus.Aux[_1, _2, _3]]

Slide 16

Slide 16 text

HLists!

Slide 17

Slide 17 text

trait Nat trait Z extends Nat trait Succ[A <: Nat] extends Nat trait HList trait HNil extends HList trait HCons[A, T <: HList] extends HList

Slide 18

Slide 18 text

trait Length[L <: HList] { type Res <: Nat } object Length { type Aux[L <: HList, Res1 <: Nat] = Length[L] { type Res = Res1 } implicit val baseCase: Aux[HNil.type, Z] = new Length[HNil.type] { type Res = Z } implicit def inductiveCase[H, T <: HList, N <: Nat] (implicit ev0: Length.Aux[T, N]) = new Length[HCons[H, T]] { type Res = Succ[N] } }

Slide 19

Slide 19 text

Shapeless! https://github.com/milessabin/shapeless

Slide 20

Slide 20 text

There's a Prolog in your Scala

Slide 21

Slide 21 text

Typelog! https://github.com/densh/typelog

Slide 22

Slide 22 text

Json

Slide 23

Slide 23 text

Danke! @folone https://soundcloud.com/jobs https://github.com/folone/fby