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

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.

Daniela Sfregola

March 17, 2018
Tweet

More Decks by Daniela Sfregola

Other Decks in Programming

Transcript

  1. A PRAGMATIC INTRODUCTION TO
    CATEGORY THEORY
    @DANIELASFREGOLA
    SCALA MATSURI 2018
    github.com/DanielaSfregola/tutorial-cat

    View Slide

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

    View Slide

  3. View Slide

  4. I AM NOT A MATHEMATICIAN

    View Slide

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

    View Slide

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

    View Slide

  7. CATEGORY THEORY
    DEEPER UNDERSTANDING ON
    OUR CODE

    View Slide

  8. HOW DO WE
    REASON ?

    View Slide

  9. COMPOSITION
    ABSTRACTION

    View Slide

  10. CATEGORY THEORY
    HOW THINGS COMPOSE

    View Slide

  11. ARROW THEORY
    CATEGORY THEORY
    HOW THINGS COMPOSE

    View Slide

  12. WHAT IS A CATEGORY?

    View Slide

  13. COMPOSITION LAW

    View Slide

  14. IDENTITY LAW

    View Slide

  15. COMPOSITION + ASSOCIATIVITY

    View Slide

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

    View Slide

  17. A PRACTICAL EXAMPLE

    View Slide

  18. CATEGORY WITH 1 OBJECT

    View Slide

  19. CATEGORY WITH 1
    OBJECT
    =
    MONOID

    View Slide

  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

    View Slide

  21. A PRACTICAL EXAMPLE

    View Slide

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

    View Slide

  23. EXERCISES ON MONOID
    > Define a monoid for Int
    > Define a monoid for String
    sbt 'testOnly *Monoid*'
    github.com/DanielaSfregola/tutorial-cat

    View Slide

  24. CATEGORY WITH 1+ OBJECT

    View Slide

  25. CATEGORY IN A BOX

    View Slide

  26. CATEGORY IN A BOX
    > Objects are in a Box
    > All the arrows are mapped

    View Slide

  27. LIFTING: CONTEXT VS CONTENT

    View Slide

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

    View Slide

  29. CATEGORY IN A BOX
    =
    FUNCTOR

    View Slide

  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)

    View Slide

  31. LIFTING: CONTEXT VS CONTENT

    View Slide

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

    View Slide

  33. EXERCISES ON FUNCTOR
    > Define a functor for Maybe
    > Define a functor for ZeroOrMore
    sbt 'testOnly *Functor*'
    github.com/DanielaSfregola/tutorial-cat

    View Slide

  34. BOX FUNCTION + BOX VALUES

    View Slide

  35. COMBINE MORE BOXES
    =
    APPLICATIVE

    View Slide

  36. APPLICATIVE'S RULES
    > Identity
    > Associativity
    > Homorphism
    > Interchange
    ...and more!

    View Slide

  37. COMBINE BOXES TOGETHER
    > How to create a new box
    > How to combine their values together

    View Slide

  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
    }

    View Slide

  39. BOX FUNCTION + BOX VALUES

    View Slide

  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
    }

    View Slide

  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

    View Slide

  42. BOX IN A BOX

    View Slide

  43. BOX IN A BOX

    View Slide

  44. FUSE TWO BOXES
    =
    MONAD

    View Slide

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

    View Slide

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

    View Slide

  47. BOXES IN A SEQUENCE

    View Slide

  48. FOR-COMPREHENSION
    val boxA: Box[A]
    def toBoxB: A => Box[B]
    def toBoxC: B => Box[C]
    def toBoxD: C => Box[D]
    for { a b c d } yield d

    View Slide

  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] = ???
    }

    View Slide

  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

    View Slide

  51. EXERCISES ON MONAD (2)
    > Define a monad for Maybe
    > Define a monad for ZeroOrMore
    sbt 'testOnly *Monad*'
    github.com/DanielaSfregola/tutorial-cat

    View Slide

  52. FUNCTOR VS ENDOFUNCTOR

    View Slide

  53. MONAD IS
    A MONOID
    IN THE CATEGORY OF
    ENDOFUNCTORS

    View Slide

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

    View Slide

  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

    View Slide

  56. View Slide

  57. FORGET ABOUT THE DETAILS
    FOCUS ON
    HOW THINGS
    COMPOSE

    View Slide

  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

    View Slide

  59. THANK YOU!
    > Twitter: @DanielaSfregola
    > Blog: danielasfregola.com
    github.com/DanielaSfregola/tutorial-cat

    View Slide