what are monads?
TRANSCRIPT
![Page 2: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/2.jpg)
But �rst...
![Page 3: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/3.jpg)
What is functional programming?
![Page 4: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/4.jpg)
Functional programming!A programming paradigm that:
treats functions as �rst class citicens
encourages immutability
avoids global state
makes your code honest
Avoids side effects (encourages purity)
![Page 5: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/5.jpg)
What are side effects?Everything that your code does, apart of operatingwith values.
![Page 6: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/6.jpg)
How can we implement this?public int sum(Int a, Int b) { // ??? }
![Page 7: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/7.jpg)
public int sum(int a, int b) { launchMissiles(); // Side effect! return a + b; }
public int sum(int a, int b) { this.pass = 4; // Side effect! return a + b; }
public int sum(int a, int b) { throw new Exception("message"); // Side effect! return a + b; }
![Page 8: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/8.jpg)
More bits of FP
![Page 9: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/9.jpg)
Imagine thisclass IO { def read(): String = readLine()// reads from standard input def write(text: String): Unit = println(text)// writes to standard output}
you could use it in the following way:
def hello(): String = { write("what is your name?") val name = read() val hello = "hello" + name write(hello) return hello }
![Page 10: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/10.jpg)
The good part:
That that code is idiomatic and concise!
The bad part:
That code is not pure! (has side effects)
![Page 11: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/11.jpg)
How can we �x this?
![Page 12: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/12.jpg)
Transform this
class IO { def read(): String = readLine() def write(text: String): Unit = println(text) }
![Page 13: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/13.jpg)
Into this!
This is our small IO language
trait IO[A] case class Read() extends IO[String] case class Write(str: String) extends IO[Unit]
This kind of construction is called Algebraic DataType.
![Page 14: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/14.jpg)
InterpreterSince our previous ADT is not effectful, meaning thatcan not execute side effects, we need its companion,the interpreter!
def interpret(op: IO[A]): A = op match { case Read() => readLine() case Write(text) => printLn(text) }
![Page 15: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/15.jpg)
Now, let's write our hellofunction!def pureHello(): IO[String] = { Write("what is your name?") val name: IO[String] = Read() Write("hello" + name) // ERROR!, you can not concat // String and IO[String] }
![Page 16: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/16.jpg)
How can we �x it?Lets add a way to sequence IO operations to ourADT!
trait IO[A] case class Read() extends IO[String] case class Write(str: String) extends IO[Unit] case class Sequence[A, B]( fa: IO[A], fn: A => IO[B]) extends IO[B]
![Page 17: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/17.jpg)
Can we write hello now?def pureHello: IO[String] = { Sequence( Write("What is your name?"), (_) => { Sequence( Read(), (name) => { Write("hello, " + name) } ) }) }
We can't! we are returning an IO[Unit] , because ofthe last Write() ... Lets �x that!
![Page 18: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/18.jpg)
Add another case to our ADTLet's add a way to put values inside IO
trait IO[A] case class Read() extends IO[String] case class Write(str: String) extends IO[Unit] case class Sequence[A, B]( fa: IO[A], fn: A => IO[B]) extends IO[B] case class Point[A](a: A) extends IO[A]
![Page 19: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/19.jpg)
Finally, we can write it now!def pureHello: IO[String] = { Sequence( Write("What is your name?"), (_) => { Sequence( Read(), (name) => { Sequence( Write("hello, " + name), (_) => { Point("hello, " + name) } ) } ) }) }
![Page 20: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/20.jpg)
The good parts
That code is pure!
The bad parts
THAT CODE IS UGLY
![Page 21: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/21.jpg)
Let's �x that!
![Page 22: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/22.jpg)
Introducing TypeClassesTypeclasses are a way to give more behaviour to anclass. You can think of them like interfaces in OOP.
But better
Much better
![Page 23: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/23.jpg)
Some typeclasses
trait Eq[A] { def equals(a: A, b: A): Bool } val intEquality = new Eq[Int] { def equals(a: Int, b: Int) = a == b }
trait Show[A] { def show(a: A): String } val showInt = new ToString[Int] { def show(a: Int) = a.toString }
![Page 24: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/24.jpg)
Guess what?
![Page 25: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/25.jpg)
Monad is a typeclass!
![Page 26: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/26.jpg)
![Page 27: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/27.jpg)
![Page 28: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/28.jpg)
Monad
trait Monad[M[_]] { def point[A](a: A): M[A] def flatMap[A, B](ma: M[A])(fn: A => M[B]): M[B] }
![Page 29: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/29.jpg)
What are monads?Monad is a typeclass for de�ning imperativelanguages.
![Page 30: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/30.jpg)
Back to our IO exampleRemember all the weirdness we needed to do inorder to do our pureHello function?
We are really close to simplifying it a lot!
Let's create a Monad instance for our IO language�rst!
val ioMonad = new Monad[IO] { def point[A](a: A): IO[A] = Point(a) def flatMap[A, B](ma: IO[A])(fn: A => IO[B]): IO[B] = Sequence(ma, fn) }
![Page 31: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/31.jpg)
Now, let's rewrite our pureHello
def pureHello: IO[String] = for { _ <- Write("What's your name?") name <- Read() _ <- Write("Hello, " + name) } yield "Hello, " + name
We only need to review our interpreter...
![Page 32: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/32.jpg)
New interpreterdef ioInterp[A](op: IO[A]): A = op match { case Write(text) => println(text) case Read() => readLine() case Point(x) => x case Sequence(x, fn) => ioInterp(fn(ioInterp(x))) }
![Page 33: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/33.jpg)
And, combine!ioInterp(pureHello()) // this actually does IO // thanks to the interpreter
![Page 34: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/34.jpg)
Small recapFunctional programming is cool
Typeclasses are here to help
Monad is for imperative programming
Monads + Interpreters = WIN!
![Page 35: What are monads?](https://reader031.vdocument.in/reader031/viewer/2022030300/588132c51a28ab00438b7099/html5/thumbnails/35.jpg)
We are done,
thanks!@jlgarhdez