SlideShare a Scribd company logo
1 of 79
Download to read offline
One Monad to Rule
Them All
Functional JVM Meetup
Prague, Aug 8 2019
John A. De Goes — @jdegoes
Agenda
1. INTRO TO
FUNCTIONAL EFFECTS
2
2. TOUR OF THE
EFFECT ZOO
3. VERTICAL
EFFECT COMPOSITION
4. INTRO TO
EFFECT ROTATION
5. PRACTICE OF
EFFECT ROTATION
1.
INTRO TO FUNCTIONAL
EFFECTS
3
1. Intro to Functional Effects
4
World of Values
Variables
Remove Duplication
In a Single Expression
Functions
Remove Duplication
Across Multple
Expressions
Combinators
Remove Higher-Order
Duplication Across
Expressions
Testing
Test Values for
Equality, Similarity,
Inequality
1. Intro to Functional Effects
5
World of Values
Variables
Remove Duplication
In a Single Expression
Functions
Remove Duplication
Across Multple
Expressions
Combinators
Remove Higher-Order
Duplication Across
Expressions
Testing
Test Values for
Equality, Similarity,
Inequality
1. Intro to Functional Effects
6
World of Values
Variables
Remove Duplication
In a Single Expression
Functions
Remove Duplication
Across Multple
Expressions
Combinators
Remove Higher-Order
Duplication Across
Expressions
Testing
Test Values for
Equality, Similarity,
Inequality
1. Intro to Functional Effects
7
World of Values
Variables
Remove Duplication
In a Single Expression
Functions
Remove Duplication
Across Multple
Expressions
Combinators
Remove Higher-Order
Duplication Across
Expressions
Testing
Test Values for
Equality, Similarity,
Inequality
1. Intro to Functional Effects
8
World of Values
Variables
Remove Duplication
In a Single Expression
Functions
Remove Duplication
Across Multple
Expressions
Combinators
Remove Higher-Order
Duplication Across
Expressions
Testing
Test Values for
Equality, Similarity,
Inequality
Cases
Packages
Types
Fields
Input/Output
Methods
1. Intro to Functional Effects
9
● GO RUNNING
1. Intro to Functional Effects
def monitor: Boolean = {
if (sensor.tripped) {
securityCompany.call()
true
} else false
}
10
1. Intro to Functional Effects
11
sealed trait Alarm[+A]
case class Return [A](v : A) extends Alarm[A]
case class CheckTripped[A](f : Boolean => Alarm[A]) extends Alarm[A]
case class Call [A](next: Alarm[A]) extends Alarm[A]
val check: Alarm[Boolean] =
CheckTripped(tripped =>
if (tripped) Call(Return(true)) else Return(false))
1. Intro to Functional Effects
12
● GO RUNNING
Execution
(Interpretation)
1. Intro to Functional Effects
13
def interpret[A](alarm: Alarm[A]): A = alarm match {
case Return(v) => v
case CheckTripped(f) => interpret(f(sensor.tripped))
case Call(next) => securityCompany.call(); interpret(next)
}
1. Intro to Functional Effects
14
"A functional effect is an immutable data type equipped with a set
of core operations that together provide a complete, type-safe
model of a domain concern."
— John A. De Goes
1. Intro to Functional Effects
15
For every concern, there is a functional effect
Concern Effect Execution
Optionality Option[A] null or A
Disjunction Either[A, B] A or B
Nondeterminism List[A] Option[A]
Input/Output IO[A] throw or A
16
Optionality
(The Painful Way)
1. Intro to Functional Effects
17
A functional effect for optionality
Maybe[A]
Succeeds with values of type A
1. Intro to Functional Effects
18
A functional effect for optionality
Operation Signature
Present A => Maybe[A]
Absent Maybe[Nothing]
Map (Maybe[A], A => B) => Maybe[B]
Chain (Maybe[A], A => Maybe[B]) => Maybe[B]
1. Intro to Functional Effects
19
sealed trait Maybe[+A]
case class Present[A](value: A) extends Maybe[A]
case object Absent extends Maybe[Nothing]
case class Map[A, B](maybe: Maybe[A], mapper: A => B) extends Maybe[B]
case class Chain[A, B](first: Maybe[A], callback: A => Maybe[B]) extends Maybe[B]
A functional effect for optionality
1. Intro to Functional Effects
20
sealed trait Maybe[+A] { self =>
def map[B](f: A => B): Maybe[B] = Map(self, f)
def flatMap[B](f: A => Maybe[B]): Maybe[B] = Chain(self, f)
}
object Maybe {
def present[A](value: A): Maybe[A] = Present[A]
val absent: Maybe[Nothing] = Absent
}
A functional effect for optionality
1. Intro to Functional Effects
def interpret[Z, A](ifAbsent: Z, f: A => Z)(maybe: Maybe[A]): Z =
maybe match {
case Present(a) => f(a)
case Absent => ifAbsent
case Map(old, f0) => interpret(ifAbsent, f.compose(f0))(old)
case Chain(old, f) =>
interpret(ifAbsent, a => interpret(ifAbsent, f)(f(a)))(old)
}
21
A functional effect for optionality
1. Intro to Functional Effects
22
Core operations for functional effects
Operation Signature Functional Type Class
pure / point A => F[A] Applicative
empty / zero F[Nothing] MonadPlus
map (F[A], A => B) => F[B] Functor
flatMap (F[A], A => F[B]) => F[B] Monad
zip / ap [F[A], F[B]) => F[(A, B)] Apply
1. Intro to Functional Effects
23
For comprehension syntax for monadic effects
1. Intro to Functional Effects
for {
user <- lookupUser(userId)
profile <- user.profile
pic <- profile.picUrl
} yield pic
lookupUser(userId).flatMap(user =>
user.profile.flatMap(profile =>
profile.picUrl.map(pic =>
pic)))
2.
TOUR OF THE
EFFECT ZOO
24
25
The functional effect of optionality
2. Tour of the Effect Zoo
sealed trait Option[+A]
final case class Some[+A](value: A) extends Option[A]
case object None extends Option[Nothing]
Option[A]
26
The functional effect of optionality
2. Tour of the Effect Zoo
// Core operations:
def some[A](v: A): Option[A] = Some(a)
val none: Option[Nothing] = None
def map[A, B](o: Option[A], f: A => B): Option[B]
def flatMap[B, B](o: Option[A], f: A => Option[B]): Option[B]
// Execution / Interpretation:
def fold[Z](z: Z)(f: A => Z)(o: Option[A]): Z
Option[A]
27
The functional effect of optionality
2. Tour of the Effect Zoo
for {
user <- lookupUser(userId)
profile <- user.profile
pic <- profile.picUrl
} yield pic
Option[A]
28
The functional effect of failure
2. Tour of the Effect Zoo
sealed trait Either[+E, +A]
final case class Left[+E](value: E) extends Either[E, Nothing]
case class Right[+A](value: A) extends Eitherr[Nothing, A]
Either[E, A]
29
The functional effect of failure
2. Tour of the Effect Zoo
Either[E, A]
// Core operations:
def left[E](e: E): Either[E, Nothing] = Left(e)
def right[A](a: A): Either[Nothing, A] = Right(a)
def map[E, A, B](o: Either[E, A], f: A => B): Either[E, B]
def flatMap[E, A, B](o: Either[E, A], f: A => Either[E, B]): Either[E, B]
// Execution / Interpretation:
def fold[Z, E, A](left: E => Z, right: A => Z)(e: Either[E, A]): Z
30
The functional effect of failure
2. Tour of the Effect Zoo
for {
user <- decodeUser(json1)
profile <- decodeProfile(json2)
pic <- decodeImage(profile.encPic)
} yield (user, profile, pic)
Either[E, A]
31
The functional effect of logging
2. Tour of the Effect Zoo
final case class Writer[+W, +A](run: (Vector[W], A))
Writer[W, A]
32
The functional effect of logging
2. Tour of the Effect Zoo
Writer[W, A]
// Core operations:
def pure[A](a: A): Writer[Nothing, A] = Writer((Vector(), a))
def write[W](w: W): Writer[W, Unit] = Writer((Vector(w), ()))
def map[W, A, B](o: Writer[W, A], f: A => B): Writer[W, B]
def flatMap[W, A, B](o: Writerr[W, A], f: A => Writer[W, B]): Writer[W, B]
// Execution / Interpretation:
def run[W, A](writer: Writer[W, A]): (Vector[W], A)
33
The functional effect of logging
2. Tour of the Effect Zoo
for {
user <- pure(findUser())
_ <- log(s"Got user: $user")
_ <- pure(getProfile(user))
_ <- log(s"Got profile: $profile")
} yield user
Writer[W, A]
34
The functional effect of state
2. Tour of the Effect Zoo
final case class State[S, +A](run: S => (S, A))
State[S, A]
35
The functional effect of state
2. Tour of the Effect Zoo
State[S, A]
// Core operations:
def pure[S, A](a: A): State[S, A] = State[S, A](s => (s, a))
def get[S]: State[S, S] = State[S, S](s => (s, s))
def set[S](s: S): State[S, Unit] = State[S, S](_ => (s, ()))
def map[S, A, B](o: State[S, A], f: A => B): State[S, B]
def flatMap[S, A, B](o: State[S, A], f: A => State[S, B]): State[S, B]
// Execution / Interpretation:
def run[S, A](s: S, state: State[S, A]): (S, A)
36
The functional effect of state
2. Tour of the Effect Zoo
for {
_ <- set(0)
v <- get
_ <- set(v + 1)
v <- get
} yield v
State[S, A]
37
The functional effect of reader
2. Tour of the Effect Zoo
final case class Reader[-R, +A](run: R => A)
Reader[R, A]
38
The functional effect of reader
2. Tour of the Effect Zoo
Reader[R, A]
// Core operations:
def pure[A](a: A): Reader[Any, A] = Reader[Any, A](_ => a)
def environment: Reader[R, R] = Reader[R, R](r => r)
def map[R, A, B](r: Reader[R, A], f: A => B): Reader[R, B]
def flatMap[R, A, B](r: Reader[R, A], f: A => Reader[R, B]): Reader[R, B]
// Execution / Interpretation:
def provide[R, A](r: R, reader: Reader[R, A]): A
39
The functional effect of reader
2. Tour of the Effect Zoo
for {
port <- environment[Config].map(_.port)
server <- environment[Config].map(_.server)
retries <- environment[Config].map(_.retries)
} yield (port, server, retries)
Reader[R, A]
40
The functional effect of asynchronous input/output
2. Tour of the Effect Zoo
final case class IO[+A](unsafeRun: (Try[A] => Unit) => Unit)
IO[A]
41
The functional effect of asynchronous input/output
2. Tour of the Effect Zoo
// Core operations:
def sync[A](v: => A): IO[A] = IO(_(Success(v)))
def async[A](r: (Try[A] => Unit) => Unit): IO[A] = IO(r)
def fail(t: Throwable): IO[Nothing] = IO(_(Failure(t)))
def map[A, B](o: IO[A], f: A => B): IO[B]
def flatMap[B, B](o: IO[A], f: A => IO[B]): IO[B]
// Execution / Interpretation:
def unsafeRun[A](io: IO[A], k: Try[A] => Unit): Unit
IO[A]
3.
VERTICAL EFFECT
COMPOSITION
42
43
Option + Either
3. Vertical Effect Composition
44
3. Vertical Effect Composition
final case class OptionEither[+E, +A](run: Either[E, Option[A]]) {
def map[B](f: A => B): OptionEither[E, B] = ???
def flatMap[B](f: A => OptionEither[E, B]): OptionEither[E, B] = ???
}
object OptionEither {
def pure[A](a: A): OptionEither[Nothing, A] = lift(Some(a))
def lift[A](option: Option[A]): OptionEither[Nothing, A] =
OptionEither(Right(option))
}
Vertical composition of Option atop Either
45
3. Vertical Effect Composition
final case class OptionT[F[_], +A](run: F[Option[A]]) {
def map[B](f: A => B)(implicit F: Functor[F]): OptionT[F, B] = ???
def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B] = ???
}
object OptionT {
def pure[A](a: A)(implicit F: Applicative[F]): OptionT[F, A] = lift(Some(a))
def lift[A](option: Option[A])(implicit F: Applicative[F]): OptionT[F, A] =
OptionT(F.pure(option))
}
Vertical composition of Option atop F[_]
46
3. Vertical Effect Composition
def myCode[F[_]: Monad]: F[Result] = {
// Introduce state effect locally:
def inner: StateT[F, MyState, Result] = ???
// Eliminate state effect locally:
inner.run(MyState.Initial)
}
Monad transformers allow local effect introduction / elimination
47
3. Vertical Effect Composition
"Monad transformers allow modular composition of separate
functional effect types into a single functional effect, with the
ability to locally introduce and eliminate effect types."
— John A. De Goes
48
Option +
Either +
Writer +
State +
Reader
3. Vertical Effect Composition
49
type GodMonad[+E, +W, S, -R, A] =
OptionT[
EitherT[
WriterT[
StateT[
Reader[R, ?],
S, ?],
W, ?],
E, ?],
?]
3. Vertical Effect Composition
50
3. Vertical Effect Composition
val effect: GodMonad[Throwable, String, Int, Config, Int] =
OptionT(
EitherT(
WriterT(
StateT(
Reader(_ => 42)))))
Monad transformers are extremely cumbersome to use directly!
51
3. Vertical Effect Composition
Monad transformers cripple performance even with opaque types!
F
OptionT[F]
StateT[EitherT[OptionT[F, ?], E, ?], S, ?]
...
52
3. Vertical Effect Composition
StateT[EitherT[F, E, ?], S, ?]
!=
EitherT[StateT[F, S, ?], E, ?]
Monad transformers are extremely order-sensitive!
n layers = n! possible orderings
53
3. Vertical Effect Composition
def myCode[F[_]: Monad]: F[Result] = {
// Cannot simply introduce / eliminate
// monad state for deeper levels!!!
def inner[G[_]: Monad](implicit G: MonadState[G, MyState, ?]): G[Result] = ???
inner[F] // Will not compile!
}
Tagless-final obliterates local effect introduction / elimination!
54
3. Vertical Effect Composition
MonadError[StateT[EitherT[IO, MyError, ?], MyState, ?], MyError, ?]
Due to encoding + compiler, transformers infer poorly!
55
3. Vertical Effect Composition
Monad transformerr checklist
Monad Transformers
Intro / Elimination ✅
Type-Inference ❌
Order-Insensitive ❌
Encapsulated ✅
Ergonomic ❌
4.
INTRO TO
EFFECT ROTATION
56
57
4. Intro to Effect Rotation
sealed trait Either[+A, +B]
case class Left [A](value: A) extends Either[A, Nothing]
case class Right[B](value: B) extends Either[Nothing, B]
Either is the simplest possible failure + success effect
58
4. Intro to Effect Rotation
// Introduction:
def fail[E](e: E): Either[E, Nothing]
// Elimination:
def catchAll[E, A](et: Either[E, A])(f: E => A): Either[Nothing, A]
Either is the simplest possible failure + success effect
Compile-time proof of elimination
59
4. Intro to Effect Rotation
final case class REither[-R, +E, +A](run: R => Either[E, A])
Why stop with error effects?
60
4. Intro to Effect Rotation
// Introduction:
def environment[R]: REither[R, Nothing, R] = REither(r => Right(r))
// Elimination:
def provide[R, E, A](r: R)(re: REither[R, E, A]): REither[Any, E, A] =
REither[Any, E, A](_ => re.run(re))
Introduction and elimination for the reader effect
Compile-time proof of elimination
61
4. Intro to Effect Rotation
final case class REither[-R, +E, +A](run: R => Either[E, A])
Naive encoding shares some overhead with transformers
Dispatch + Boxing Overhead
62
4. Intro to Effect Rotation
63
4. Intro to Effect Rotation
MTL[R, W, S, E, A]
64
4. Intro to Effect Rotation
sealed trait MTL[-R, +W, S, +E, +A] { self =>
def map[B](f: A => B): MTL[R, W, S, E, B] = ???
def flatMap[..](f: A => MTL[R1, W1, S, E1, B]): MTL[R1, W1, S, E1, B] = ???
// Optimized interpreter for GADT:
def run(r: R, s: S): (List[W], S, Either[E, A]) = ???
}
Possible to eliminate overhead with "free" encodings
65
4. Intro to Effect Rotation
object MTL {
final case class Succeed[S, +A](value: A) extends MTL[Any, Nothing, S, Nothing, A]
final case class Reader [R, S]() extends MTL[R, Nothing, S, Nothing, R]
final case class RunReader[R, +W, S, +E, +A](r: R, mtl: MTL[R, W, S, E, A]) extends MTL[Any, W, S, E, A]
final case class Error [S, +E](error: E) extends MTL[Any, Nothing, S, E, Nothing]
final case class RunError[-R, +W, S, +E, +A](mtl: MTL[R, W, S, E, A]) extends MTL[Any, W, S, Nothing, Either[E, A]]
final case class State [S, +A](f: S => (S, A)) extends MTL[Any, Nothing, S, Nothing, A]
final case class RunState[-R, +W, S, +E, +A](s: S, mtl: MTL[R, W, S, E, A]) extends MTL[R, W, Unit, E, A]
final case class Writer [+W, S](w: W) extends MTL[Any, W, S, Nothing, Unit]
final case class RunWriter[-R, +W, S, +E, +A](mtl: MTL[R, W, S, E, A]) extends MTL[R, Nothing, S, E, (List[W], A)]
final case class FlatMap[R, W, S, E, A, R1 <: R, W1 >: W, E1 >: E, B](first: MTL[R, W, S, E, A], k: A => MTL[R1, W1, S, E1, B]) extends
MTL[R1, W1, S, E1, B]
}
Possible to eliminate overhead with "free" encodings
66
4. Intro to Effect Rotation
Elimination laws for effect rotation
Effect Type Type Elimination Examples
Covariant Nothing Failure, Optionality,
Writer
Contravariant Any Reader
Invariant Unit State
67
4. Intro to Effect Rotation
Monad transformers versus effect rotation
Monad Transformers Effect Rotation
Intro / Elimination ✅ ✅
Type-Inference ❌ ✅
Order-Insensitive ❌ ✅
Encapsulated ✅ ❌
Ergonomic ❌ ✅
5.
PRACTICE OF
EFFECT ROTATION
68
69
5. Practice of Effect Rotation
ZIO[R, E, A]
Reader
Error
Success
70
5. Practice of Effect Rotation
Reader
trait ZIO[R, E, A] {
def provide(r: R): ZIO[Any, E, A] = ???
}
object ZIO {
def environment: ZIO[R, Nothing, R] = ???
def accessM[R, E, A](f: R => ZIO[R, E, A]): ZIO[R, E, A] = ???
}
71
5. Practice of Effect Rotation
Error
trait ZIO[R, E, A] {
def either: ZIO[R, Nothing, Either[E, A]] = ???
}
object ZIO {
def fail(e: E): ZIO[Any, E, Nothing] = ???
def succeed(a: A): ZIO[Any, Nothing, A] = ???
}
72
5. Practice of Effect Rotation
Option via Error
ZIO[R, Unit, A]
73
5. Practice of Effect Rotation
Option + Either via Error
ZIO[R, Option[E], A]
74
5. Practice of Effect Rotation
trait Ref[A] {
def update(f: A => A): UIO[A]
def modify[B](f: A => (B, A)): UIO[B]
def get: UIO[A]
def set(a: A): UIO[Unit]
}
Reader + Ref / TRef is the key to unlocking other effects!
75
5. Practice of Effect Rotation
Writer via Reader
trait Writer[W] {
def writer: Ref[Vector[W]]
}
def write[W](w: W): ZIO[Writer[W], Nothing, Unit] =
ZIO.accessM[Writer[W]](_.writer.update(_ :+ w).unit)
76
5. Practice of Effect Rotation
State via Reader
trait State[S] {
def state: Ref[S]
}
def modify[S, A](f: S => (S, A)): ZIO[State[S], Nothing, A] =
ZIO.accessM[State[S]](_.state.modify(f))
def update[S, A](f: S => S): ZIO[State[S], Nothing, Unit] = modify(s => (s, ()))
def gets[S]: ZIO[State[S], Nothing, S] = modify(s => (s, s))
77
5. Practice of Effect Rotation
God Monad
type Fx[S, W] = State[S] with Writer[W]
type GodMonad2[+E, W, S, -R <: Fx[S, W], A] =
ZIO[R, Option[E], A]
78
5. Practice of Effect Rotation
Effect rotation delivers resource / concurrent safety!
Monad Transformers Effect Rotation
... ... ...
Concurrent-Safe State ❌ ✅
Concurrrent Safe Writer ❌ ✅
Resource-Safe State ❌ ✅
Resource-Safe Writer ❌ ✅
THANK YOU!
Any questions?
You should follow me on Twitter:
@jdegoes
And bookmark my blog:
http://degoes.net
79

More Related Content

What's hot

Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with CatsMark Canlas
 
Production-ready GraphQL with Caliban
Production-ready GraphQL with CalibanProduction-ready GraphQL with Caliban
Production-ready GraphQL with CalibanPierre Ricadat
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!MeriamLachkar1
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...Philip Schwarz
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event LoopDesignveloper
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021Natan Silnitsky
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside💡 Tomasz Kogut
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018John De Goes
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in ScalaHermann Hueck
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick SmackdownAlexander Ioffe
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type ClassesJohn De Goes
 
Why The Free Monad isn't Free
Why The Free Monad isn't FreeWhy The Free Monad isn't Free
Why The Free Monad isn't FreeKelley Robinson
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaExploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaJorge Vásquez
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongMario Fusco
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Piotr Paradziński
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaVladimir Kostyukov
 
Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0Jorge Vásquez
 

What's hot (20)

Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with Cats
 
Production-ready GraphQL with Caliban
Production-ready GraphQL with CalibanProduction-ready GraphQL with Caliban
Production-ready GraphQL with Caliban
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
 
The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...The aggregate function - from sequential and parallel folds to parallel aggre...
The aggregate function - from sequential and parallel folds to parallel aggre...
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside
 
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018Blazing Fast, Pure Effects without Monads — LambdaConf 2018
Blazing Fast, Pure Effects without Monads — LambdaConf 2018
 
Preparing for Scala 3
Preparing for Scala 3Preparing for Scala 3
Preparing for Scala 3
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick Smackdown
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
Why The Free Monad isn't Free
Why The Free Monad isn't FreeWhy The Free Monad isn't Free
Why The Free Monad isn't Free
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Exploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in ScalaExploring ZIO Prelude: The game changer for typeclasses in Scala
Exploring ZIO Prelude: The game changer for typeclasses in Scala
 
If You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are WrongIf You Think You Can Stay Away from Functional Programming, You Are Wrong
If You Think You Can Stay Away from Functional Programming, You Are Wrong
 
Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...Big picture of category theory in scala with deep dive into contravariant and...
Big picture of category theory in scala with deep dive into contravariant and...
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
 
Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0Programación Funcional 101 con Scala y ZIO 2.0
Programación Funcional 101 con Scala y ZIO 2.0
 

Similar to One Monad to Rule Them All

Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2Hang Zhao
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and EffectsRaymond Roestenburg
 
Introductory part of function for class 12th JEE
Introductory part of function for class 12th JEEIntroductory part of function for class 12th JEE
Introductory part of function for class 12th JEEMohanSonawane
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2Hang Zhao
 
Talk - Query monad
Talk - Query monad Talk - Query monad
Talk - Query monad Fabernovel
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsDebasish Ghosh
 
Actors and functional_reactive_programming
Actors and functional_reactive_programmingActors and functional_reactive_programming
Actors and functional_reactive_programmingDiego Alonso
 
Kotlin For Android - Functions (part 3 of 7)
Kotlin For Android - Functions (part 3 of 7)Kotlin For Android - Functions (part 3 of 7)
Kotlin For Android - Functions (part 3 of 7)Gesh Markov
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adtsHang Zhao
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
Composition birds-and-recursion
Composition birds-and-recursionComposition birds-and-recursion
Composition birds-and-recursionDavid Atchley
 
Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and EffectsDylan Forciea
 
Python programming workshop session 3
Python programming workshop session 3Python programming workshop session 3
Python programming workshop session 3Abdul Haseeb
 
Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...Scalac
 
Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersPiotr Paradziński
 
Programming withmatlab
Programming withmatlabProgramming withmatlab
Programming withmatlabnehanairm
 

Similar to One Monad to Rule Them All (20)

Fp in scala with adts part 2
Fp in scala with adts part 2Fp in scala with adts part 2
Fp in scala with adts part 2
 
Zio from Home
Zio from Home Zio from Home
Zio from Home
 
Berlin meetup
Berlin meetupBerlin meetup
Berlin meetup
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
 
Introductory part of function for class 12th JEE
Introductory part of function for class 12th JEEIntroductory part of function for class 12th JEE
Introductory part of function for class 12th JEE
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
 
Talk - Query monad
Talk - Query monad Talk - Query monad
Talk - Query monad
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain Models
 
Actors and functional_reactive_programming
Actors and functional_reactive_programmingActors and functional_reactive_programming
Actors and functional_reactive_programming
 
Kotlin For Android - Functions (part 3 of 7)
Kotlin For Android - Functions (part 3 of 7)Kotlin For Android - Functions (part 3 of 7)
Kotlin For Android - Functions (part 3 of 7)
 
Fp in scala with adts
Fp in scala with adtsFp in scala with adts
Fp in scala with adts
 
Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
Composition birds-and-recursion
Composition birds-and-recursionComposition birds-and-recursion
Composition birds-and-recursion
 
Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and Effects
 
Python programming workshop session 3
Python programming workshop session 3Python programming workshop session 3
Python programming workshop session 3
 
Advanced JavaScript
Advanced JavaScript Advanced JavaScript
Advanced JavaScript
 
Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...Why functional programming and category theory strongly matters - Piotr Parad...
Why functional programming and category theory strongly matters - Piotr Parad...
 
Why functional programming and category theory strongly matters
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly matters
 
Programming withmatlab
Programming withmatlabProgramming withmatlab
Programming withmatlab
 

More from John De Goes

Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIOJohn De Goes
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }John De Goes
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final TaglessJohn De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: RebirthJohn De Goes
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingJohn De Goes
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New GameJohn De Goes
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsJohn De Goes
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional ArchitectureJohn De Goes
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemJohn De Goes
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsJohn De Goes
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free MonadsJohn De Goes
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!John De Goes
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...John De Goes
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and FutureJohn De Goes
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!John De Goes
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScriptJohn De Goes
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsJohn De Goes
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming LanguageJohn De Goes
 

More from John De Goes (20)

Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
The Death of Final Tagless
The Death of Final TaglessThe Death of Final Tagless
The Death of Final Tagless
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional ProgrammingZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
ZIO Schedule: Conquering Flakiness & Recurrence with Pure Functional Programming
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
 
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & AnalyticsQuark: A Purely-Functional Scala DSL for Data Processing & Analytics
Quark: A Purely-Functional Scala DSL for Data Processing & Analytics
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
 
Getting Started with PureScript
Getting Started with PureScriptGetting Started with PureScript
Getting Started with PureScript
 
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual AnalyticsSlamData - How MongoDB Is Powering a Revolution in Visual Analytics
SlamData - How MongoDB Is Powering a Revolution in Visual Analytics
 
The Next Great Functional Programming Language
The Next Great Functional Programming LanguageThe Next Great Functional Programming Language
The Next Great Functional Programming Language
 

Recently uploaded

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 

Recently uploaded (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 

One Monad to Rule Them All

  • 1. One Monad to Rule Them All Functional JVM Meetup Prague, Aug 8 2019 John A. De Goes — @jdegoes
  • 2. Agenda 1. INTRO TO FUNCTIONAL EFFECTS 2 2. TOUR OF THE EFFECT ZOO 3. VERTICAL EFFECT COMPOSITION 4. INTRO TO EFFECT ROTATION 5. PRACTICE OF EFFECT ROTATION
  • 4. 1. Intro to Functional Effects 4 World of Values Variables Remove Duplication In a Single Expression Functions Remove Duplication Across Multple Expressions Combinators Remove Higher-Order Duplication Across Expressions Testing Test Values for Equality, Similarity, Inequality
  • 5. 1. Intro to Functional Effects 5 World of Values Variables Remove Duplication In a Single Expression Functions Remove Duplication Across Multple Expressions Combinators Remove Higher-Order Duplication Across Expressions Testing Test Values for Equality, Similarity, Inequality
  • 6. 1. Intro to Functional Effects 6 World of Values Variables Remove Duplication In a Single Expression Functions Remove Duplication Across Multple Expressions Combinators Remove Higher-Order Duplication Across Expressions Testing Test Values for Equality, Similarity, Inequality
  • 7. 1. Intro to Functional Effects 7 World of Values Variables Remove Duplication In a Single Expression Functions Remove Duplication Across Multple Expressions Combinators Remove Higher-Order Duplication Across Expressions Testing Test Values for Equality, Similarity, Inequality
  • 8. 1. Intro to Functional Effects 8 World of Values Variables Remove Duplication In a Single Expression Functions Remove Duplication Across Multple Expressions Combinators Remove Higher-Order Duplication Across Expressions Testing Test Values for Equality, Similarity, Inequality Cases Packages Types Fields Input/Output Methods
  • 9. 1. Intro to Functional Effects 9 ● GO RUNNING
  • 10. 1. Intro to Functional Effects def monitor: Boolean = { if (sensor.tripped) { securityCompany.call() true } else false } 10
  • 11. 1. Intro to Functional Effects 11 sealed trait Alarm[+A] case class Return [A](v : A) extends Alarm[A] case class CheckTripped[A](f : Boolean => Alarm[A]) extends Alarm[A] case class Call [A](next: Alarm[A]) extends Alarm[A] val check: Alarm[Boolean] = CheckTripped(tripped => if (tripped) Call(Return(true)) else Return(false))
  • 12. 1. Intro to Functional Effects 12 ● GO RUNNING Execution (Interpretation)
  • 13. 1. Intro to Functional Effects 13 def interpret[A](alarm: Alarm[A]): A = alarm match { case Return(v) => v case CheckTripped(f) => interpret(f(sensor.tripped)) case Call(next) => securityCompany.call(); interpret(next) }
  • 14. 1. Intro to Functional Effects 14 "A functional effect is an immutable data type equipped with a set of core operations that together provide a complete, type-safe model of a domain concern." — John A. De Goes
  • 15. 1. Intro to Functional Effects 15 For every concern, there is a functional effect Concern Effect Execution Optionality Option[A] null or A Disjunction Either[A, B] A or B Nondeterminism List[A] Option[A] Input/Output IO[A] throw or A
  • 16. 16 Optionality (The Painful Way) 1. Intro to Functional Effects
  • 17. 17 A functional effect for optionality Maybe[A] Succeeds with values of type A 1. Intro to Functional Effects
  • 18. 18 A functional effect for optionality Operation Signature Present A => Maybe[A] Absent Maybe[Nothing] Map (Maybe[A], A => B) => Maybe[B] Chain (Maybe[A], A => Maybe[B]) => Maybe[B] 1. Intro to Functional Effects
  • 19. 19 sealed trait Maybe[+A] case class Present[A](value: A) extends Maybe[A] case object Absent extends Maybe[Nothing] case class Map[A, B](maybe: Maybe[A], mapper: A => B) extends Maybe[B] case class Chain[A, B](first: Maybe[A], callback: A => Maybe[B]) extends Maybe[B] A functional effect for optionality 1. Intro to Functional Effects
  • 20. 20 sealed trait Maybe[+A] { self => def map[B](f: A => B): Maybe[B] = Map(self, f) def flatMap[B](f: A => Maybe[B]): Maybe[B] = Chain(self, f) } object Maybe { def present[A](value: A): Maybe[A] = Present[A] val absent: Maybe[Nothing] = Absent } A functional effect for optionality 1. Intro to Functional Effects
  • 21. def interpret[Z, A](ifAbsent: Z, f: A => Z)(maybe: Maybe[A]): Z = maybe match { case Present(a) => f(a) case Absent => ifAbsent case Map(old, f0) => interpret(ifAbsent, f.compose(f0))(old) case Chain(old, f) => interpret(ifAbsent, a => interpret(ifAbsent, f)(f(a)))(old) } 21 A functional effect for optionality 1. Intro to Functional Effects
  • 22. 22 Core operations for functional effects Operation Signature Functional Type Class pure / point A => F[A] Applicative empty / zero F[Nothing] MonadPlus map (F[A], A => B) => F[B] Functor flatMap (F[A], A => F[B]) => F[B] Monad zip / ap [F[A], F[B]) => F[(A, B)] Apply 1. Intro to Functional Effects
  • 23. 23 For comprehension syntax for monadic effects 1. Intro to Functional Effects for { user <- lookupUser(userId) profile <- user.profile pic <- profile.picUrl } yield pic lookupUser(userId).flatMap(user => user.profile.flatMap(profile => profile.picUrl.map(pic => pic)))
  • 25. 25 The functional effect of optionality 2. Tour of the Effect Zoo sealed trait Option[+A] final case class Some[+A](value: A) extends Option[A] case object None extends Option[Nothing] Option[A]
  • 26. 26 The functional effect of optionality 2. Tour of the Effect Zoo // Core operations: def some[A](v: A): Option[A] = Some(a) val none: Option[Nothing] = None def map[A, B](o: Option[A], f: A => B): Option[B] def flatMap[B, B](o: Option[A], f: A => Option[B]): Option[B] // Execution / Interpretation: def fold[Z](z: Z)(f: A => Z)(o: Option[A]): Z Option[A]
  • 27. 27 The functional effect of optionality 2. Tour of the Effect Zoo for { user <- lookupUser(userId) profile <- user.profile pic <- profile.picUrl } yield pic Option[A]
  • 28. 28 The functional effect of failure 2. Tour of the Effect Zoo sealed trait Either[+E, +A] final case class Left[+E](value: E) extends Either[E, Nothing] case class Right[+A](value: A) extends Eitherr[Nothing, A] Either[E, A]
  • 29. 29 The functional effect of failure 2. Tour of the Effect Zoo Either[E, A] // Core operations: def left[E](e: E): Either[E, Nothing] = Left(e) def right[A](a: A): Either[Nothing, A] = Right(a) def map[E, A, B](o: Either[E, A], f: A => B): Either[E, B] def flatMap[E, A, B](o: Either[E, A], f: A => Either[E, B]): Either[E, B] // Execution / Interpretation: def fold[Z, E, A](left: E => Z, right: A => Z)(e: Either[E, A]): Z
  • 30. 30 The functional effect of failure 2. Tour of the Effect Zoo for { user <- decodeUser(json1) profile <- decodeProfile(json2) pic <- decodeImage(profile.encPic) } yield (user, profile, pic) Either[E, A]
  • 31. 31 The functional effect of logging 2. Tour of the Effect Zoo final case class Writer[+W, +A](run: (Vector[W], A)) Writer[W, A]
  • 32. 32 The functional effect of logging 2. Tour of the Effect Zoo Writer[W, A] // Core operations: def pure[A](a: A): Writer[Nothing, A] = Writer((Vector(), a)) def write[W](w: W): Writer[W, Unit] = Writer((Vector(w), ())) def map[W, A, B](o: Writer[W, A], f: A => B): Writer[W, B] def flatMap[W, A, B](o: Writerr[W, A], f: A => Writer[W, B]): Writer[W, B] // Execution / Interpretation: def run[W, A](writer: Writer[W, A]): (Vector[W], A)
  • 33. 33 The functional effect of logging 2. Tour of the Effect Zoo for { user <- pure(findUser()) _ <- log(s"Got user: $user") _ <- pure(getProfile(user)) _ <- log(s"Got profile: $profile") } yield user Writer[W, A]
  • 34. 34 The functional effect of state 2. Tour of the Effect Zoo final case class State[S, +A](run: S => (S, A)) State[S, A]
  • 35. 35 The functional effect of state 2. Tour of the Effect Zoo State[S, A] // Core operations: def pure[S, A](a: A): State[S, A] = State[S, A](s => (s, a)) def get[S]: State[S, S] = State[S, S](s => (s, s)) def set[S](s: S): State[S, Unit] = State[S, S](_ => (s, ())) def map[S, A, B](o: State[S, A], f: A => B): State[S, B] def flatMap[S, A, B](o: State[S, A], f: A => State[S, B]): State[S, B] // Execution / Interpretation: def run[S, A](s: S, state: State[S, A]): (S, A)
  • 36. 36 The functional effect of state 2. Tour of the Effect Zoo for { _ <- set(0) v <- get _ <- set(v + 1) v <- get } yield v State[S, A]
  • 37. 37 The functional effect of reader 2. Tour of the Effect Zoo final case class Reader[-R, +A](run: R => A) Reader[R, A]
  • 38. 38 The functional effect of reader 2. Tour of the Effect Zoo Reader[R, A] // Core operations: def pure[A](a: A): Reader[Any, A] = Reader[Any, A](_ => a) def environment: Reader[R, R] = Reader[R, R](r => r) def map[R, A, B](r: Reader[R, A], f: A => B): Reader[R, B] def flatMap[R, A, B](r: Reader[R, A], f: A => Reader[R, B]): Reader[R, B] // Execution / Interpretation: def provide[R, A](r: R, reader: Reader[R, A]): A
  • 39. 39 The functional effect of reader 2. Tour of the Effect Zoo for { port <- environment[Config].map(_.port) server <- environment[Config].map(_.server) retries <- environment[Config].map(_.retries) } yield (port, server, retries) Reader[R, A]
  • 40. 40 The functional effect of asynchronous input/output 2. Tour of the Effect Zoo final case class IO[+A](unsafeRun: (Try[A] => Unit) => Unit) IO[A]
  • 41. 41 The functional effect of asynchronous input/output 2. Tour of the Effect Zoo // Core operations: def sync[A](v: => A): IO[A] = IO(_(Success(v))) def async[A](r: (Try[A] => Unit) => Unit): IO[A] = IO(r) def fail(t: Throwable): IO[Nothing] = IO(_(Failure(t))) def map[A, B](o: IO[A], f: A => B): IO[B] def flatMap[B, B](o: IO[A], f: A => IO[B]): IO[B] // Execution / Interpretation: def unsafeRun[A](io: IO[A], k: Try[A] => Unit): Unit IO[A]
  • 43. 43 Option + Either 3. Vertical Effect Composition
  • 44. 44 3. Vertical Effect Composition final case class OptionEither[+E, +A](run: Either[E, Option[A]]) { def map[B](f: A => B): OptionEither[E, B] = ??? def flatMap[B](f: A => OptionEither[E, B]): OptionEither[E, B] = ??? } object OptionEither { def pure[A](a: A): OptionEither[Nothing, A] = lift(Some(a)) def lift[A](option: Option[A]): OptionEither[Nothing, A] = OptionEither(Right(option)) } Vertical composition of Option atop Either
  • 45. 45 3. Vertical Effect Composition final case class OptionT[F[_], +A](run: F[Option[A]]) { def map[B](f: A => B)(implicit F: Functor[F]): OptionT[F, B] = ??? def flatMap[B](f: A => OptionT[F, B])(implicit F: Monad[F]): OptionT[F, B] = ??? } object OptionT { def pure[A](a: A)(implicit F: Applicative[F]): OptionT[F, A] = lift(Some(a)) def lift[A](option: Option[A])(implicit F: Applicative[F]): OptionT[F, A] = OptionT(F.pure(option)) } Vertical composition of Option atop F[_]
  • 46. 46 3. Vertical Effect Composition def myCode[F[_]: Monad]: F[Result] = { // Introduce state effect locally: def inner: StateT[F, MyState, Result] = ??? // Eliminate state effect locally: inner.run(MyState.Initial) } Monad transformers allow local effect introduction / elimination
  • 47. 47 3. Vertical Effect Composition "Monad transformers allow modular composition of separate functional effect types into a single functional effect, with the ability to locally introduce and eliminate effect types." — John A. De Goes
  • 48. 48 Option + Either + Writer + State + Reader 3. Vertical Effect Composition
  • 49. 49 type GodMonad[+E, +W, S, -R, A] = OptionT[ EitherT[ WriterT[ StateT[ Reader[R, ?], S, ?], W, ?], E, ?], ?] 3. Vertical Effect Composition
  • 50. 50 3. Vertical Effect Composition val effect: GodMonad[Throwable, String, Int, Config, Int] = OptionT( EitherT( WriterT( StateT( Reader(_ => 42))))) Monad transformers are extremely cumbersome to use directly!
  • 51. 51 3. Vertical Effect Composition Monad transformers cripple performance even with opaque types! F OptionT[F] StateT[EitherT[OptionT[F, ?], E, ?], S, ?] ...
  • 52. 52 3. Vertical Effect Composition StateT[EitherT[F, E, ?], S, ?] != EitherT[StateT[F, S, ?], E, ?] Monad transformers are extremely order-sensitive! n layers = n! possible orderings
  • 53. 53 3. Vertical Effect Composition def myCode[F[_]: Monad]: F[Result] = { // Cannot simply introduce / eliminate // monad state for deeper levels!!! def inner[G[_]: Monad](implicit G: MonadState[G, MyState, ?]): G[Result] = ??? inner[F] // Will not compile! } Tagless-final obliterates local effect introduction / elimination!
  • 54. 54 3. Vertical Effect Composition MonadError[StateT[EitherT[IO, MyError, ?], MyState, ?], MyError, ?] Due to encoding + compiler, transformers infer poorly!
  • 55. 55 3. Vertical Effect Composition Monad transformerr checklist Monad Transformers Intro / Elimination ✅ Type-Inference ❌ Order-Insensitive ❌ Encapsulated ✅ Ergonomic ❌
  • 57. 57 4. Intro to Effect Rotation sealed trait Either[+A, +B] case class Left [A](value: A) extends Either[A, Nothing] case class Right[B](value: B) extends Either[Nothing, B] Either is the simplest possible failure + success effect
  • 58. 58 4. Intro to Effect Rotation // Introduction: def fail[E](e: E): Either[E, Nothing] // Elimination: def catchAll[E, A](et: Either[E, A])(f: E => A): Either[Nothing, A] Either is the simplest possible failure + success effect Compile-time proof of elimination
  • 59. 59 4. Intro to Effect Rotation final case class REither[-R, +E, +A](run: R => Either[E, A]) Why stop with error effects?
  • 60. 60 4. Intro to Effect Rotation // Introduction: def environment[R]: REither[R, Nothing, R] = REither(r => Right(r)) // Elimination: def provide[R, E, A](r: R)(re: REither[R, E, A]): REither[Any, E, A] = REither[Any, E, A](_ => re.run(re)) Introduction and elimination for the reader effect Compile-time proof of elimination
  • 61. 61 4. Intro to Effect Rotation final case class REither[-R, +E, +A](run: R => Either[E, A]) Naive encoding shares some overhead with transformers Dispatch + Boxing Overhead
  • 62. 62 4. Intro to Effect Rotation
  • 63. 63 4. Intro to Effect Rotation MTL[R, W, S, E, A]
  • 64. 64 4. Intro to Effect Rotation sealed trait MTL[-R, +W, S, +E, +A] { self => def map[B](f: A => B): MTL[R, W, S, E, B] = ??? def flatMap[..](f: A => MTL[R1, W1, S, E1, B]): MTL[R1, W1, S, E1, B] = ??? // Optimized interpreter for GADT: def run(r: R, s: S): (List[W], S, Either[E, A]) = ??? } Possible to eliminate overhead with "free" encodings
  • 65. 65 4. Intro to Effect Rotation object MTL { final case class Succeed[S, +A](value: A) extends MTL[Any, Nothing, S, Nothing, A] final case class Reader [R, S]() extends MTL[R, Nothing, S, Nothing, R] final case class RunReader[R, +W, S, +E, +A](r: R, mtl: MTL[R, W, S, E, A]) extends MTL[Any, W, S, E, A] final case class Error [S, +E](error: E) extends MTL[Any, Nothing, S, E, Nothing] final case class RunError[-R, +W, S, +E, +A](mtl: MTL[R, W, S, E, A]) extends MTL[Any, W, S, Nothing, Either[E, A]] final case class State [S, +A](f: S => (S, A)) extends MTL[Any, Nothing, S, Nothing, A] final case class RunState[-R, +W, S, +E, +A](s: S, mtl: MTL[R, W, S, E, A]) extends MTL[R, W, Unit, E, A] final case class Writer [+W, S](w: W) extends MTL[Any, W, S, Nothing, Unit] final case class RunWriter[-R, +W, S, +E, +A](mtl: MTL[R, W, S, E, A]) extends MTL[R, Nothing, S, E, (List[W], A)] final case class FlatMap[R, W, S, E, A, R1 <: R, W1 >: W, E1 >: E, B](first: MTL[R, W, S, E, A], k: A => MTL[R1, W1, S, E1, B]) extends MTL[R1, W1, S, E1, B] } Possible to eliminate overhead with "free" encodings
  • 66. 66 4. Intro to Effect Rotation Elimination laws for effect rotation Effect Type Type Elimination Examples Covariant Nothing Failure, Optionality, Writer Contravariant Any Reader Invariant Unit State
  • 67. 67 4. Intro to Effect Rotation Monad transformers versus effect rotation Monad Transformers Effect Rotation Intro / Elimination ✅ ✅ Type-Inference ❌ ✅ Order-Insensitive ❌ ✅ Encapsulated ✅ ❌ Ergonomic ❌ ✅
  • 69. 69 5. Practice of Effect Rotation ZIO[R, E, A] Reader Error Success
  • 70. 70 5. Practice of Effect Rotation Reader trait ZIO[R, E, A] { def provide(r: R): ZIO[Any, E, A] = ??? } object ZIO { def environment: ZIO[R, Nothing, R] = ??? def accessM[R, E, A](f: R => ZIO[R, E, A]): ZIO[R, E, A] = ??? }
  • 71. 71 5. Practice of Effect Rotation Error trait ZIO[R, E, A] { def either: ZIO[R, Nothing, Either[E, A]] = ??? } object ZIO { def fail(e: E): ZIO[Any, E, Nothing] = ??? def succeed(a: A): ZIO[Any, Nothing, A] = ??? }
  • 72. 72 5. Practice of Effect Rotation Option via Error ZIO[R, Unit, A]
  • 73. 73 5. Practice of Effect Rotation Option + Either via Error ZIO[R, Option[E], A]
  • 74. 74 5. Practice of Effect Rotation trait Ref[A] { def update(f: A => A): UIO[A] def modify[B](f: A => (B, A)): UIO[B] def get: UIO[A] def set(a: A): UIO[Unit] } Reader + Ref / TRef is the key to unlocking other effects!
  • 75. 75 5. Practice of Effect Rotation Writer via Reader trait Writer[W] { def writer: Ref[Vector[W]] } def write[W](w: W): ZIO[Writer[W], Nothing, Unit] = ZIO.accessM[Writer[W]](_.writer.update(_ :+ w).unit)
  • 76. 76 5. Practice of Effect Rotation State via Reader trait State[S] { def state: Ref[S] } def modify[S, A](f: S => (S, A)): ZIO[State[S], Nothing, A] = ZIO.accessM[State[S]](_.state.modify(f)) def update[S, A](f: S => S): ZIO[State[S], Nothing, Unit] = modify(s => (s, ())) def gets[S]: ZIO[State[S], Nothing, S] = modify(s => (s, s))
  • 77. 77 5. Practice of Effect Rotation God Monad type Fx[S, W] = State[S] with Writer[W] type GodMonad2[+E, W, S, -R <: Fx[S, W], A] = ZIO[R, Option[E], A]
  • 78. 78 5. Practice of Effect Rotation Effect rotation delivers resource / concurrent safety! Monad Transformers Effect Rotation ... ... ... Concurrent-Safe State ❌ ✅ Concurrrent Safe Writer ❌ ✅ Resource-Safe State ❌ ✅ Resource-Safe Writer ❌ ✅
  • 79. THANK YOU! Any questions? You should follow me on Twitter: @jdegoes And bookmark my blog: http://degoes.net 79