Slide 1

Slide 1 text

Generating Type Class Instances Automatically Scala Workshop 2013 Lars Hupel TU München July 2nd, 2013

Slide 2

Slide 2 text

Agenda 1 Type Classes in Scala 2 Representing data types 3 Abstracting over Type Classes 2 / 13

Slide 3

Slide 3 text

Type Classes in Scala ▶ Scala offers no built-in support for type classes ▶ encoding with traits and implicits ▶ full power of the language available Oliveira, Bruno C. D. S., Moors, Adriaan, and Odersky, Martin Type Classes as Objects and Implicits 3 / 13

Slide 4

Slide 4 text

Implementing instances class Vector2D(val x: Int, val y: Int) class Vector3D(val x: Int, val y: Int, val z: Int) ▶ we want: default instances for ... ▶ Semigroup (pointwise addition) ▶ Order (lexicographic order) ▶ and more? ▶ very repetitive to implement by hand ▶ need a mechanism to automate that task 4 / 13

Slide 5

Slide 5 text

Implementing instances class Vector2D(val x: Int, val y: Int) class Vector3D(val x: Int, val y: Int, val z: Int) ▶ we want: default instances for ... ▶ Semigroup (pointwise addition) ▶ Order (lexicographic order) ▶ and more? ▶ very repetitive to implement by hand ▶ need a mechanism to automate that task 4 / 13

Slide 6

Slide 6 text

Implementing instances class Vector2D(val x: Int, val y: Int) class Vector3D(val x: Int, val y: Int, val z: Int) ▶ Scala already provides some automation ▶ generates: ▶ toString ▶ equals ▶ hashCode ▶ but: baked into the compiler 4 / 13

Slide 7

Slide 7 text

Implementing instances case class Vector2D(x: Int, y: Int) case class Vector3D(x: Int, y: Int, z: Int) ▶ Scala already provides some automation ▶ generates: ▶ toString ▶ equals ▶ hashCode ▶ but: baked into the compiler 4 / 13

Slide 8

Slide 8 text

Implementing instances case class Vector2D(x: Int, y: Int) case class Vector3D(x: Int, y: Int, z: Int) ▶ Scala already provides some automation ▶ generates: ▶ toString ▶ equals ▶ hashCode ▶ but: baked into the compiler 4 / 13

Slide 9

Slide 9 text

Implementing instances case class Vector2D(x: Int, y: Int) case class Vector3D(x: Int, y: Int, z: Int) ▶ Scala already provides some automation ▶ generates: ▶ toString ▶ equals ▶ hashCode ▶ but: baked into the compiler 4 / 13

Slide 10

Slide 10 text

Implementing instances case class Vector2D(x: Int, y: Int) case class Vector3D(x: Int, y: Int, z: Int) ▶ Scala already provides some automation ▶ generates: ▶ toString ▶ equals ▶ hashCode ▶ but: baked into the compiler 4 / 13

Slide 11

Slide 11 text

Agenda 1 Type Classes in Scala 2 Representing data types 3 Abstracting over Type Classes 5 / 13

Slide 12

Slide 12 text

The essence of data types ▶ we are dealing with algebraic data types ▶ ... consisting of one or more cases ▶ ... consisting of zero or more fields 6 / 13

Slide 13

Slide 13 text

The essence of data types ▶ we are dealing with coproducts ▶ ... consisting of one or more products Magalhães, Jose P., Dijsktra, Atze, Jeuring, Johan, and Löh, Andres A generic deriving mechanism for Haskell Oliveira, Bruno C. D. S., and Gibbons, Jeremy Scala for generic programmers 6 / 13

Slide 14

Slide 14 text

Abstract representation Data type case class Vector3D(x: Int, y: Int, z: Int) Representation type Repr = (Int, Int, Int) 7 / 13

Slide 15

Slide 15 text

Abstract representation Data type sealed trait Shape case class Circle(radius: Int) extends Shape case class Rectangle(height: Int, width: Int) extends Shape Representation type Repr = Either[Int, (Int, Int)] 7 / 13

Slide 16

Slide 16 text

Agenda 1 Type Classes in Scala 2 Representing data types 3 Abstracting over Type Classes 8 / 13

Slide 17

Slide 17 text

Composing instances Most type classes C[_] support these operations: product C[A] => C[B] => C[(A, B)] project C[B] => (A => B, B => A) => C[A] coproduct C[A] => C[B] => C[Either[A, B]] 9 / 13

Slide 18

Slide 18 text

Composing instances Most type classes C[_] support these operations: product C[A] => C[B] => C[(A, B)] project C[B] => (A => B, B => A) => C[A] coproduct C[A] => C[B] => C[Either[A, B]] 9 / 13

Slide 19

Slide 19 text

Instances for data types Input Data type T Type class C[_] Output Instance C[T] 10 / 13

Slide 20

Slide 20 text

Instances for data types Algorithm 1. analyze data type, compute representation result: type Repr 2. construct conversions results: T => Repr, Repr => T 3. gather base instances result: e.g. C[Int], C[String], ... 4. compose base instances using product and coproduct result: C[Repr] 5. use project to obtain final instance result: C[T] 11 / 13

Slide 21

Slide 21 text

Instances for data types Algorithm 1. analyze data type, compute representation result: type Repr 2. construct conversions results: T => Repr, Repr => T 3. gather base instances result: e.g. C[Int], C[String], ... 4. compose base instances using product and coproduct result: C[Repr] 5. use project to obtain final instance result: C[T] 11 / 13

Slide 22

Slide 22 text

Instances for data types Algorithm 1. analyze data type, compute representation result: type Repr 2. construct conversions results: T => Repr, Repr => T 3. gather base instances result: e.g. C[Int], C[String], ... 4. compose base instances using product and coproduct result: C[Repr] 5. use project to obtain final instance result: C[T] 11 / 13

Slide 23

Slide 23 text

Instances for data types Algorithm 1. analyze data type, compute representation result: type Repr 2. construct conversions results: T => Repr, Repr => T 3. gather base instances result: e.g. C[Int], C[String], ... 4. compose base instances using product and coproduct result: C[Repr] 5. use project to obtain final instance result: C[T] 11 / 13

Slide 24

Slide 24 text

Instances for data types Algorithm 1. analyze data type, compute representation result: type Repr 2. construct conversions results: T => Repr, Repr => T 3. gather base instances result: e.g. C[Int], C[String], ... 4. compose base instances using product and coproduct result: C[Repr] 5. use project to obtain final instance result: C[T] 11 / 13

Slide 25

Slide 25 text

Problems ▶ base instances are resolved via regular implicit search ▶ What happens for (mutually) recursive data types? ▶ solution: make macro aware of recursion (aka tying the knot) ▶ self recursion: easy, use this instead of implicitly ▶ mutual recursion: require user setup ▶ indirect recursion: ongoing ... 12 / 13

Slide 26

Slide 26 text

Problems ▶ base instances are resolved via regular implicit search ▶ What happens for (mutually) recursive data types? ▶ solution: make macro aware of recursion (aka tying the knot) ▶ self recursion: easy, use this instead of implicitly ▶ mutual recursion: require user setup ▶ indirect recursion: ongoing ... 12 / 13

Slide 27

Slide 27 text

Q & A @larsr h larsrh.github.io typelevel.org/blog github.com/milessabin/shapeless