Either, Some or None
An introduction to monadic structures and
functional programming
September 29th, São Paulo, Brazil
#monads #functional_programming #category_theory_applied
What I would like to know about
monadic structures and monads
Slide 4
Slide 4 text
Why talk about monads?
● Implemented in major modern languages:
● Provides simple ways of express complex computation;
● They are hard to read about because of specific vocabulary;
Slide 5
Slide 5 text
Goals
● A soft theory of Monad
● Monodic structures and operations
● Some common monads
● Real use cases
● Recap
Slide 6
Slide 6 text
WTF is a Monad?
Slide 7
Slide 7 text
If this than that
Monads express decisions about how and which conditions a software
should execute.
It allows you to handle and route different inputs/outputs without
repeating yourself.
Slide 8
Slide 8 text
It's a design pattern to describe and
manipulate flows of data
Interacting with the Monads
● Map
● Filter
● Aggregate
● Group
Slide 11
Slide 11 text
The 3 Monadic laws
trait Monoid[A] {
// The identity
def get[A]: A
// The functor
def map[B](f: A => B): Monad[B]
// The bind
def flatMap[B](f: A => Monad[B]): Monad[B]
}
Scala
Slide 12
Slide 12 text
Show me the Monads
Slide 13
Slide 13 text
The optional pattern
val aString: String = "Hello, world!"
val len: Int = aString.length
Scala
Slide 14
Slide 14 text
The optional pattern
val aString: String = null
val len: Int = aString.length
//=> java.lang.NullPointerException
Scala
Slide 15
Slide 15 text
The optional pattern
val maybeString: Option[String] = Some("Hello, world!")
val maybeLen: Int = maybeString.map(_.length).getOrElse(-1)
Scala
Slide 16
Slide 16 text
The optional pattern
val maybeString: String? = "Hello, world!"
val maybeLen = maybeString?.length ?: -1
Kotlin
Slide 17
Slide 17 text
The optional pattern
let maybeString: String? = "Hello, world!"
let maybeLen = maybeString.length ?? -1
Swift
Slide 18
Slide 18 text
The continuation monad
(some-> (maybe-a-result from-db)
(then-do-something)
(then-another)
(and-finishes))
Clojure
Execute if last result is not nil
It will return the value or nil
Pass the result to the next fn
Slide 19
Slide 19 text
Call me Maybe
s::String -> Maybe String
s "" = Nothing
s x = Just x
Haskell
Slide 20
Slide 20 text
The identity monad
val query: Option[String] = Option(myNullableOutput)
query match {
case Some(q) => myTable.filter(_.name == q)
case None => myTable.all()
}
Scala
Slide 21
Slide 21 text
Exception handling
val maybeAnOperation: Try[Any] = Try {
potentiallyHarmfulOperation()
} match {
case Success(s: Any) => ???
case Failure(e: ArithmeticException) => ???
case Failure(e: Exception) => ???
}
Scala
Either this or that
val json: Either[JsError, JsSuccess] = parse("""{"foo": "bar"}""")
json match {
case JsSuccess(o) => println("OK")
case JsError(err) => println(err.list)
}
Scala
Right or left identity
def httpRequest(input: Either[Valid, Invalid]): HttpResponse =
input.fold(
left => HttpResponse(StatusCodes.BadRequest),
right => HttpResponse(StatusCodes.OK))
Scala
Assigning callbacks
firstTask.flatMap(secondTask).flatMap(thirdTask)
.runAsync {
case Success(s) => // Perform side effects
case Failure(e) => // Do something on failure
}
Scalaz
Slide 32
Slide 32 text
It's all about Promises
let eventualResponse = new Promise(function() {
setTimeout(() => resolve("Hello, world!"), 2000)
})
eventualResponse
.then(applyFunctor)
.then(msg => console.log("Apply side-effects!"))
ES2016
Slide 33
Slide 33 text
The observable pattern
val observer = new Observer[Any] {
def onNext(elem: Any): Future[Ack] =
Continue
def onError(ex: Throwable): Unit =
ex.printStackTrace()
def onComplete(): Unit =
println("Completed")
}
Monix
Slide 34
Slide 34 text
Observable operations
● Group by batches or time intervals;
● Fork and merge streams;
● Handle errors and apply retry strategies;
● Delay execution and back-pressure.
Slide 35
Slide 35 text
Becoming reactive
Rx.Observable.webSocket('ws://localhost:8000')
.retryWhen((errors) => {
return Rx.Observable.timer(5000) // retry in 5 secs
})
.groupBy((msg) => msg.category)
.throttle(1000) // One message per sec and discard the rest
.subscribe((msgs) => console.log(msgs))
ES2016
Slide 36
Slide 36 text
Recapping the monads
● Maybe is useful to handle failures scenarios;
● Either for validations and data deserialization;
● Future lets you create asynchronous operations;
Slide 37
Slide 37 text
Monads FTW
● SwiftZ and Runes for Swift
● Kathegory for Kotlin
● Scalaz, Cats and Monix for Scala
● ReactiveX (aka Rx): Scala, C#, C++, Kotlin, Swift and many others
Slide 38
Slide 38 text
Homework
● Reader and Writer Monads
● Monad Transformers
● Free Monad and Free Applicative
● Lenses, Kleisli, and others;