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 full-size slide

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

    View full-size slide

  3. I AM NOT A MATHEMATICIAN

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  6. CATEGORY THEORY
    DEEPER UNDERSTANDING ON
    OUR CODE

    View full-size slide

  7. HOW DO WE
    REASON ?

    View full-size slide

  8. COMPOSITION
    ABSTRACTION

    View full-size slide

  9. CATEGORY THEORY
    HOW THINGS COMPOSE

    View full-size slide

  10. ARROW THEORY
    CATEGORY THEORY
    HOW THINGS COMPOSE

    View full-size slide

  11. WHAT IS A CATEGORY?

    View full-size slide

  12. COMPOSITION LAW

    View full-size slide

  13. IDENTITY LAW

    View full-size slide

  14. COMPOSITION + ASSOCIATIVITY

    View full-size slide

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

    View full-size slide

  16. A PRACTICAL EXAMPLE

    View full-size slide

  17. CATEGORY WITH 1 OBJECT

    View full-size slide

  18. CATEGORY WITH 1
    OBJECT
    =
    MONOID

    View full-size slide

  19. 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 full-size slide

  20. A PRACTICAL EXAMPLE

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  23. CATEGORY WITH 1+ OBJECT

    View full-size slide

  24. CATEGORY IN A BOX

    View full-size slide

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

    View full-size slide

  26. LIFTING: CONTEXT VS CONTENT

    View full-size slide

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

    View full-size slide

  28. CATEGORY IN A BOX
    =
    FUNCTOR

    View full-size slide

  29. 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 full-size slide

  30. LIFTING: CONTEXT VS CONTENT

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. BOX FUNCTION + BOX VALUES

    View full-size slide

  34. COMBINE MORE BOXES
    =
    APPLICATIVE

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  37. 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 full-size slide

  38. BOX FUNCTION + BOX VALUES

    View full-size slide

  39. 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 full-size slide

  40. 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 full-size slide

  41. BOX IN A BOX

    View full-size slide

  42. BOX IN A BOX

    View full-size slide

  43. FUSE TWO BOXES
    =
    MONAD

    View full-size slide

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

    View full-size slide

  45. 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 full-size slide

  46. BOXES IN A SEQUENCE

    View full-size slide

  47. 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

    View full-size slide

  48. 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 full-size slide

  49. 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 full-size slide

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

    View full-size slide

  51. FUNCTOR VS ENDOFUNCTOR

    View full-size slide

  52. MONAD IS
    A MONOID
    IN THE CATEGORY OF
    ENDOFUNCTORS

    View full-size slide

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

    View full-size slide

  54. 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 full-size slide

  55. FORGET ABOUT THE DETAILS
    FOCUS ON
    HOW THINGS
    COMPOSE

    View full-size slide

  56. 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 full-size slide

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

    View full-size slide