SlideShare una empresa de Scribd logo
1 de 79
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...Philip Schwarz
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Philip Schwarz
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldJorge Vásquez
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayDebasish Ghosh
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and EffectsMartin Odersky
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...Philip Schwarz
 
Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Victor Rentea
 
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
 
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
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlinintelliyole
 
Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Andrii Lashchenko
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...Philip Schwarz
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in ScalaHermann Hueck
 

La actualidad más candente (20)

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...
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Applicative Functor
Applicative FunctorApplicative Functor
Applicative Functor
 
State Monad
State MonadState Monad
State Monad
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
 
Applicative style programming
Applicative style programmingApplicative style programming
Applicative style programming
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...Sum and Product Types -The Fruit Salad & Fruit Snack Example - From F# to Ha...
Sum and Product Types - The Fruit Salad & Fruit Snack Example - From F# to Ha...
 
Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8Clean Lambdas & Streams in Java8
Clean Lambdas & Streams in Java8
 
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
 
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
 
Lazy java
Lazy javaLazy java
Lazy java
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Left and Right Folds- Comparison of a mathematical definition and a programm...Left and Right Folds- Comparison of a mathematical definition and a programm...
Left and Right Folds - Comparison of a mathematical definition and a programm...
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 

Similar a 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
 
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
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside💡 Tomasz Kogut
 
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
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
 
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
 
Programming withmatlab
Programming withmatlabProgramming withmatlab
Programming withmatlabnehanairm
 

Similar a 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
 
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
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside
 
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
Why functional programming and category theory strongly mattersWhy functional programming and category theory strongly matters
Why functional programming and category theory strongly matters
 
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...
 
Programming withmatlab
Programming withmatlabProgramming withmatlab
Programming withmatlab
 

Más de John De Goes

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type ClassesJohn 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
 

Más de John De Goes (20)

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
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
 
ZIO Queue
ZIO QueueZIO Queue
ZIO Queue
 
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
 

Último

unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dashnarutouzumaki53779
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 

Último (20)

unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dash
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 

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