ScalaMatsuri 2018 - A pragmatic introduction to Category Theory

ScalaMatsuri 2018 - A pragmatic introduction to Category Theory

Category Theory has become one of the hot topics in the community. Why is this theory suddenly so interesting for developers? Why are the cool kids talking so much about it?

This talk will introduce the general principles of Category Theory in a pragmatic, non-mathematical way. We will show practical examples of how this theory has managed to simplify and solve common challenges that we encounter in our code daily, such as nullable values, error handling, parallel and sequential operations and data validation. Also, we will apply them to create our own category theory library from scratch using ScalaCheck as the only dependency.

E99b07644586e9e1723757bf8e34ea68?s=128

Daniela Sfregola

March 17, 2018
Tweet

Transcript

  1. A PRAGMATIC INTRODUCTION TO CATEGORY THEORY @DANIELASFREGOLA SCALA MATSURI 2018

    github.com/DanielaSfregola/tutorial-cat
  2. AGENDA - Intro - Monoid - Functor - Applicative -

    Monad github.com/DanielaSfregola/tutorial-cat
  3. None
  4. I AM NOT A MATHEMATICIAN

  5. YOU DO NOT NEED TO KNOW CATEGORY THEORY TO WRITE

    GOOD CODE
  6. YOU DO NOT NEED TO KNOW CATEGORY THEORY TO WRITE

    FUNCTIONAL CODE
  7. CATEGORY THEORY DEEPER UNDERSTANDING ON OUR CODE

  8. HOW DO WE REASON ?

  9. COMPOSITION ABSTRACTION

  10. CATEGORY THEORY HOW THINGS COMPOSE

  11. ARROW THEORY CATEGORY THEORY HOW THINGS COMPOSE

  12. WHAT IS A CATEGORY?

  13. COMPOSITION LAW

  14. IDENTITY LAW

  15. COMPOSITION + ASSOCIATIVITY

  16. CATEGORY'S RULES > Identity > Composition > Associativity

  17. A PRACTICAL EXAMPLE

  18. CATEGORY WITH 1 OBJECT

  19. CATEGORY WITH 1 OBJECT = MONOID

  20. MONOID'S RULES Identity n o id == id o n

    == n Composition forall x, y => x o y Associativity x o (y o z) == (x o y) o z
  21. A PRACTICAL EXAMPLE

  22. MONOID trait Monoid[A] { def identity: A def compose(x: A,

    y: A): A }
  23. EXERCISES ON MONOID > Define a monoid for Int >

    Define a monoid for String sbt 'testOnly *Monoid*' github.com/DanielaSfregola/tutorial-cat
  24. CATEGORY WITH 1+ OBJECT

  25. CATEGORY IN A BOX

  26. CATEGORY IN A BOX > Objects are in a Box

    > All the arrows are mapped
  27. LIFTING: CONTEXT VS CONTENT

  28. EXAMPLE OF BOXES > Option > Future > Try >

    List > Either
  29. CATEGORY IN A BOX = FUNCTOR

  30. FUNCTOR'S RULES Identity map(id) == id Composition map(g o f)

    == map(g) o map(f) Associativity map(h o g) o map(f) == map(h) o map(g o f)
  31. LIFTING: CONTEXT VS CONTENT

  32. FUNCTOR class Functor[Box[_]] { def map[A, B](boxA: Box[A]) (f: A

    => B): Box[B] }
  33. EXERCISES ON FUNCTOR > Define a functor for Maybe >

    Define a functor for ZeroOrMore sbt 'testOnly *Functor*' github.com/DanielaSfregola/tutorial-cat
  34. BOX FUNCTION + BOX VALUES

  35. COMBINE MORE BOXES = APPLICATIVE

  36. APPLICATIVE'S RULES > Identity > Associativity > Homorphism > Interchange

    ...and more!
  37. COMBINE BOXES TOGETHER > How to create a new box

    > How to combine their values together
  38. APPLICATIVE class Applicative[Box[_]] extends Functor[Box] { def pure[A](a: A): Box[A]

    def ap[A, B](boxF: Box[A => B])(boxA: Box[A]): Box[B] def map[A, B](boxA: Box[A])(f: A => B): Box[B] = ??? // spoiler alert }
  39. BOX FUNCTION + BOX VALUES

  40. APPLICATIVE class Applicative[Box[_]] extends Functor[Box] { def pure[A](a: A): Box[A]

    def ap[A, B](boxF: Box[A => B])(value: Box[A]): Box[B] def ap2[A1, A2, B](boxF: Box[(A1, A2) => B]) (value1: Box[A1], value2: Box[A2]): Box[B] // up to 22 values! // same for map }
  41. EXERCISES ON APPLICATIVE > Define map in terms of ap

    and pure > Define an applicative for Maybe > Define an applicative for ZeroOrMore sbt 'testOnly *Applicative*' github.com/DanielaSfregola/tutorial-cat
  42. BOX IN A BOX

  43. BOX IN A BOX

  44. FUSE TWO BOXES = MONAD

  45. MONAD'S RULES > Identity > Composition > Associativity

  46. MONAD (AS FUNCTOR) class Monad[Box[_]] extends Functor[Box] { def flatten[A](bb:

    Box[Box[A]]): Box[A] def flatMap[A, B](valueA: Box[A])(f: A => Box[B]): Box[B] = { val bb: Box[Box[B]] = map(valueA)(f) bb.flatten } }
  47. BOXES IN A SEQUENCE

  48. FOR-COMPREHENSION val boxA: Box[A] def toBoxB: A => Box[B] def

    toBoxC: B => Box[C] def toBoxD: C => Box[D] for { a <- boxA b <- toBoxB(a) c <- toBoxC(b) d <- toBoxD(c) } yield d
  49. MONAD (AS APPLICATIVE) trait Monad[Box[_]] extends Applicative[Box] { def flatMap[A,

    B](boxA: Box[A])(f: A => Box[B]): Box[B] // TODO - implement using flatMap def flatten[A](boxBoxA: Box[Box[A]]): Box[A] = ??? // TODO - implement using flatMap and map override def ap[A, B](boxF: Box[A => B]) (boxA: Box[A]): Box[B] = ??? // TODO - implement using flatMap and pure override def map[A, B](boxA: Box[A])(f: A => B): Box[B] = ??? }
  50. EXERCISES ON MONAD (1) > Define flatten using flatMap >

    Define map using flatMap and pure > Define ap using flatMap and map github.com/DanielaSfregola/tutorial-cat
  51. EXERCISES ON MONAD (2) > Define a monad for Maybe

    > Define a monad for ZeroOrMore sbt 'testOnly *Monad*' github.com/DanielaSfregola/tutorial-cat
  52. FUNCTOR VS ENDOFUNCTOR

  53. MONAD IS A MONOID IN THE CATEGORY OF ENDOFUNCTORS

  54. MONAD MONOID => pure + flatten ENDOFUNCTORS => map

  55. SUMMARY CATEGORY THEORY >> how things compose MONOID >> combining

    2 values into 1 FUNCTOR >> values lifted to a context APPLICATIVE >> independent values applied to a function in a context MONAD >> ops in sequence in a context
  56. None
  57. FORGET ABOUT THE DETAILS FOCUS ON HOW THINGS COMPOSE

  58. WANNA KNOW MORE? > Category Theory for the WH by

    @PhilipWadler > Category Theory by @BartoszMilewski > Cats-Infographics by Rob Norris - @tpolecat > Cats Documentation - Type Classes
  59. THANK YOU! > Twitter: @DanielaSfregola > Blog: danielasfregola.com github.com/DanielaSfregola/tutorial-cat