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

Functional Programming with Cats

Lars Hupel
February 17, 2017

Functional Programming with Cats

Lars Hupel

February 17, 2017
Tweet

More Decks by Lars Hupel

Other Decks in Programming

Transcript

  1. What’s in Cats? ▶ type classes ▶ data types ▶

    monad transformers ▶ pretty syntax ▶ optimization macros ▶ laws 4
  2. Ecosystem Alleycats Cats instances and classes which are outlaws, miscreants,

    and ne’er-do-wells Dogs Data structures for pure functional programming in Scala Kittens Automatic type class derivation for Cats 5
  3. Agenda 1 Exercise 1: Error Handling 2 Exercise 2: Trees

    3 Exercise 3: Free Monads 4 Exercise 4: Numerics 8
  4. Agenda 1 Exercise 1: Error Handling 2 Exercise 2: Trees

    3 Exercise 3: Free Monads 4 Exercise 4: Numerics 9
  5. Example def stringToInt(x: String): Either[String, Int] = { try {

    Right(x.toInt) } catch { case _: NumberFormatException => Left(s”Invalid number $x”) } } 11
  6. Example def stringToInt(x: String): Either[String, Int] for { h <-

    stringToInt(hourField) m <- stringToInt(minField) } yield Time(h, m) 11
  7. Accumulation def stringToInt(x: String): ValidatedNel[String, Int] = { try {

    Validated.valid(x.toInt) } catch { case _: NumberFormatException => Validated.invalidNel(s”Invalid number $x”) } } 12
  8. Agenda 1 Exercise 1: Error Handling 2 Exercise 2: Trees

    3 Exercise 3: Free Monads 4 Exercise 4: Numerics 14
  9. Agenda 1 Exercise 1: Error Handling 2 Exercise 2: Trees

    3 Exercise 3: Free Monads 4 Exercise 4: Numerics 18
  10. monad (n.) (in the pantheistic philosophy of Giordano Bruno) a

    fundamental metaphysical unit that is spatially extended and psychically aware – Collins English Dictionary
  11. How to structure applications In functional programming, we separate pure

    from effectful code. ▶ in OO parlance: “Domain-driven design” 21
  12. How to structure applications In functional programming, we separate pure

    from effectful code. ▶ in OO parlance: “Domain-driven design” ▶ But how do we structure effectful code? ▶ database access ▶ web requests ▶ terminal I/O ▶ ... 21
  13. The “Free Monad” approach: I/O as a DSL What do

    we need to write a terminal application? ▶ read from standard input ▶ write to standard output ▶ open file ▶ read from file ▶ ... 22
  14. The “Free Monad” approach: I/O as a DSL What do

    we need to write a terminal application? ▶ read from standard input ▶ write to standard output ▶ open file ▶ read from file ▶ ... 22
  15. A datatype for terminals sealed trait Terminal[A] case object ReadLine

    extends Terminal[String] case class WriteLine(line: String) extends Terminal[Unit] 23
  16. A datatype for terminals sealed trait Terminal[A] case object ReadLine

    extends Terminal[String] case class WriteLine(line: String) extends Terminal[Unit] ▶ Terminal is an ordinary class hierarchy ▶ nicely represents what we want ▶ But what to do with it? How do we compose it? 23
  17. A datatype for terminals sealed trait Terminal[A] case object ReadLine

    extends Terminal[String] case class WriteLine(line: String) extends Terminal[Unit] ▶ Terminal is an ordinary class hierarchy ▶ nicely represents what we want ▶ But what to do with it? How do we compose it? 23 It looks like you need a monad. Want help with that?
  18. Coyoneda? “ What is sometimes called the co-Yoneda lemma is

    a basic fact about presheaves (a basic fact of topos theory): it says that every presheaf is a colimit of representables and more precisely that it is the “colimit over itself of all the representables contained in it”. ” – nLab 24
  19. Coyoneda? “ What is sometimes called the co-Yoneda lemma is

    a basic fact about presheaves (a basic fact of topos theory): it says that every presheaf is a colimit of representables and more precisely that it is the “colimit over itself of all the representables contained in it”. ” – nLab 24
  20. Agenda 1 Exercise 1: Error Handling 2 Exercise 2: Trees

    3 Exercise 3: Free Monads 4 Exercise 4: Numerics 27
  21. Semigroup trait Semigroup[A] { def combine(x: A, y: A): A

    } Law: Associativity combine(x, combine(y, z)) == com- bine(combine(x, y), z) 28
  22. Monoids trait Monoid[A] { def combine(x: A, y: A): A

    def empty: A } Law: Neutral element combine(x, empty) == x 29
  23. Monoidal structures Lots of things are monoids. ▶ Int, BigInt,

    ... ▶ List[T] ▶ Map[K, V] ▶ ... 30