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

OptimusPrimeT

Lars Hupel
October 24, 2014

 OptimusPrimeT

Code: https://github.com/larsrh/scalaio2014

Everybody knows monads by now, so a talk about monads would hardly be worthwhile. Let's take it to the next level: monad transformers. We'll learn what they are, how they naturally emerge in your code base and how to make good use of them in Scala – and maybe even how to create your own.

Lars Hupel

October 24, 2014
Tweet

More Decks by Lars Hupel

Other Decks in Programming

Transcript

  1. (A ⊗ B) ⊗ TC αA,B,TC  tA⊗B,C // T((A

    ⊗ B) ⊗ C) T(αA,B,C )  A ⊗ (B ⊗ TC) A⊗tB,C // A ⊗ T(B ⊗ C) tA,B⊗C // T(A ⊗ (B ⊗ C))
  2. If all you have are monads ... Monads have lots

    of use cases: ▶ error handling ▶ parser combinators ▶ value-oriented parallelism ▶ ... 9
  3. Functors from the ground up Functors are about transforming data

    scala> List(1, 2, 3).map(x => x + 1) List(2, 3, 4) scala> Some(1).map(x => x + 1) Some(2) scala> Future { 1 }.map(x => x + 1) // something resembling 2 12
  4. Functors from the ground up Functors are about transforming data

    scala> List(1, 2, 3).map(x => x + 1) List(2, 3, 4) scala> Some(1).map(x => x + 1) Some(2) scala> Future { 1 }.map(x => x + 1) // something resembling 2 12
  5. The Functor class scalaz offers a generaliza on of that

    pa ern trait Functor[F[_]] { def map[A, B](f: A => B, fa: F[A]): F[B] } 13
  6. More power: Applica ves Applica ves are about transforming independent

    pieces of data scala> List(1, 2) tuple List(3, 4) List((1, 3), (1, 4), (2, 3), (2, 4)) 14
  7. The Applicative class trait Applicative[F[_]] { // from Functor def

    map[A, B] (f: A => B, fa: F[A]): F[B] def map2[A, B, C] (f: (A, B) => C, fa: F[A], fb: F[B]): F[C] } 15
  8. Even more power: Monads Monads are about transforming dependent pieces

    of data def fileRequest(user: User, file: Path): Future[Int] = for { token <- db.getAccessToken(user) input <- db.readFile(token, file) _ <- HTTP.sendHeader(HTTP.OK) written <- HTTP.sendBody(input) } yield written 16
  9. The Monad class trait Monad[F[_]] { def flatMap[A, B](f: A

    => F[B], fa: F[A]): F[B] def map2[A, B, C] (f: (A, B) => C, fa: F[A], fb: F[B]) = ??? } 17
  10. The Monad class trait Monad[F[_]] { def flatMap[A, B](f: A

    => F[B], fa: F[A]): F[B] def map2[A, B, C] (f: (A, B) => C, fa: F[A], fb: F[B]) = flatMap(a => flatMap(b => f(a, b), fb), fa) } 17
  11. Composing monads Our Tools // Monad[F] def flatMap[A, B](f: A

    => F[B], fa: F[A]): F[B] // Monad[G] def flatMap[A, B](f: A => F[B], ga: G[A]): G[B] Our Goal def flatMap[A, B] (f: A => F[G[B]], fga: F[G[A]]): F[G[B]] 25
  12. Computer Science Interlude The Hal ng Problem It is undecidable

    whether a program will terminate on a given input. 26
  13. Computer Science Interlude The Hal ng Problem It is undecidable

    whether a program will terminate on a given input. ... defeated? Yet there are programming languages which only accept termina ng programs. 26
  14. Composing par cular monads Our Tools (refined) // Monad[F] def

    flatMap[A, B](f: A => F[B], fa: F[A]): F[B] Our Goal (refined) def flatMapForOption[A, B] (f: A => F[Option[B]], foa: F[Option[A]]): F[Option[B]] 27
  15. Recap ▶ Monads are awesome, but o en too powerful.

    ▶ Functors compose. ▶ Applica ves compose. ▶ Monads do not compose in general. ▶ Specific monads do compose. ▶ That actually comes up very o en. 30