A gentle introduction to monads

Monads?

What the hell are monads you ask?

  1. person X works long and hard, and groks monads
  2. person X experiences amazing feeling of enlightenment, wonders why others are not similarly enlightened
  3. person X gives horrible, incomplete, inaccurate, oversimplified, and confusing explanation of monads to others which probably makes them think that monads are stupid, dumb, worthless, overcomplicated, unnecessary, something incorrect, or a mental wank-ercise
  • Operations that return a value or an error
  • Operations that perform operations on a List/Array
  • Operations that have an asynchronous nature.
  • Etc.
  • Execute the rest of the code only if there was no error
  • Execute the rest of the code once for each value in the list
  • Execute the rest of the code once the asynchronous code is finished
  • Etc.
  1. Give insights why it’s a powerful concept that is so much more than the implementations most object oriented programmers are familiar with (Java Optional, etc)

Scala?

Almost all the code and the examples in this blogpost are written in Scala. Why Scala you ask?

  1. Scala is the preferred programming language for many data engineers.
  2. Scala can make senior developers feel very junior. Old programmers like me like to feel young again.
  3. Scala is sexy

Back to monads?

Let’s get started and do a conceptual dive into these mysterious monads.

  1. Yes, a Java Optional is a monad because it has a FlapMap function and it’s a wrapper concept.
def unit: A → F[A]
def map: F[A] → (A → B) → F[B]
def flatten: F[F[A]] → F[A]
  1. Our M type has a trait (interface in JAVA) that says that we need a FlapMap function on our wrapper type. That FlapMap function takes a function as parameter and that function maps a type A to a type B (wrapped inside our wrapper/monad type).
unit(x).flatMap(f) == f(x)
m.flatMap(unit) == m
m.flatMap(f).flatMap(g) == m.flatMap(x ⇒ f(x).flatMap(g))

Let's dive into the world of monads laws ...
left identity law -> both below statement are equalSome(10)Some(10)right identity law -> both below statement are equalSome(5)Some(5)associativity law -> both below statement are equalSome(16)Some(16)
Let's do some sequencing ...JanJan
  1. Using the flatmap operator you can see that our flatmap function remains very clean.
the monad way ...Some(2)NoneNone
  • if it returns a Some, the flatMap method calls our function and passes us the integer aNum;
  • the second call to parseInt returns a None or a Some;
  • if it returns a Some, the flatMap method calls our function and passes us bNum;
  • the call to divide returns a None or a Some, which is our result.
  • A FlapMap function
  • An optional Map function
  1. We create our FlatMap function and remember that we will use this for sequencing a chain of operations. It’s identical to our map implementation but now we append the message instead of replacing it.
106
f: input: 100, result: 101g: input: 101, result: 103h: input: 103, result: 106
final Scala for comprehension value: 106final Scala for comprehension msg:f: input: 100, result: 101g: input: 101, result: 103h: input: 103, result: 106

father, husband and data engineer / ml engineer@continuum consulting

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store