SlideShare a Scribd company logo
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

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
 
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 Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
Philip Schwarz
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
Jorge Vásquez
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Philip Schwarz
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
Martin Odersky
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Philip Schwarz
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
Kirill Rozov
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
Wiem Zine Elabidine
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
Alexander Ioffe
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
Philip Schwarz
 
Jetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UIJetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UI
Gilang Ramadhan
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
Maxim Novak
 
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
 
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
 
Javaバイトコード入門
Javaバイトコード入門Javaバイトコード入門
Javaバイトコード入門
Kota Mizushima
 
Arriving at monads by going from pure-function composition to effectful-funct...
Arriving at monads by going from pure-function composition to effectful-funct...Arriving at monads by going from pure-function composition to effectful-funct...
Arriving at monads by going from pure-function composition to effectful-funct...
Philip Schwarz
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
Philip Schwarz
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Philip Schwarz
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside
💡 Tomasz Kogut
 

What's hot (20)

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...
 
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 Map, Filter and Fold
The Functional Programming Triad of Map, Filter and FoldThe Functional Programming Triad of Map, Filter and Fold
The Functional Programming Triad of Map, Filter and Fold
 
A Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIOA Prelude of Purity: Scaling Back ZIO
A Prelude of Purity: Scaling Back ZIO
 
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...Algebraic Data Types forData Oriented Programming - From Haskell and Scala t...
Algebraic Data Types for Data Oriented Programming - From Haskell and Scala t...
 
Capabilities for Resources and Effects
Capabilities for Resources and EffectsCapabilities for Resources and Effects
Capabilities for Resources and Effects
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - Part ...
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 
Zio in real world
Zio in real worldZio in real world
Zio in real world
 
ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022ZIO-Direct - Functional Scala 2022
ZIO-Direct - Functional Scala 2022
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
Jetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UIJetpack Compose - Android’s modern toolkit for building native UI
Jetpack Compose - Android’s modern toolkit for building native UI
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
 
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...
 
Javaバイトコード入門
Javaバイトコード入門Javaバイトコード入門
Javaバイトコード入門
 
Arriving at monads by going from pure-function composition to effectful-funct...
Arriving at monads by going from pure-function composition to effectful-funct...Arriving at monads by going from pure-function composition to effectful-funct...
Arriving at monads by going from pure-function composition to effectful-funct...
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 1
 
Taking your side effects aside
Taking your side effects asideTaking your side effects aside
Taking your side effects aside
 

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 2
Hang Zhao
 
Zio from Home
Zio from Home Zio from Home
Zio from Home
Wiem Zine Elabidine
 
Berlin meetup
Berlin meetupBerlin meetup
Berlin meetup
Wiem Zine Elabidine
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
Hermann Hueck
 
Functions, Types, Programs and Effects
Functions, Types, Programs and EffectsFunctions, Types, Programs and Effects
Functions, Types, Programs and Effects
Raymond 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 JEE
MohanSonawane
 
Fp in scala part 2
Fp in scala part 2Fp in scala part 2
Fp in scala part 2
Hang 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 Models
Debasish Ghosh
 
Actors and functional_reactive_programming
Actors and functional_reactive_programmingActors and functional_reactive_programming
Actors and functional_reactive_programming
Diego 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 adts
Hang Zhao
 
Monads do not Compose
Monads do not ComposeMonads do not Compose
Monads do not Compose
Philip Schwarz
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
league
 
Composition birds-and-recursion
Composition birds-and-recursionComposition birds-and-recursion
Composition birds-and-recursion
David Atchley
 
Functional IO and Effects
Functional IO and EffectsFunctional IO and Effects
Functional IO and Effects
Dylan Forciea
 
Python programming workshop session 3
Python programming workshop session 3Python programming workshop session 3
Python programming workshop session 3
Abdul Haseeb
 
Advanced JavaScript
Advanced JavaScript Advanced JavaScript
Advanced JavaScript
Zsolt Mészárovics
 
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
Piotr 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
 

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
 
Implementing the IO Monad in Scala
Implementing the IO Monad in ScalaImplementing the IO Monad in Scala
Implementing the IO Monad in Scala
 
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
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...
 

More from John De Goes

Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
John De Goes
 
Error Management: Future vs ZIO
Error Management: Future vs ZIOError Management: Future vs ZIO
Error Management: Future vs ZIO
John 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 Tagless
John De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
John De Goes
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
John 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 Programming
John De Goes
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
John De Goes
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
John De Goes
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
John 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 System
John 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 & Analytics
John De Goes
 
Post-Free: Life After Free Monads
Post-Free: Life After Free MonadsPost-Free: Life After Free Monads
Post-Free: Life After Free Monads
John De Goes
 
Streams for (Co)Free!
Streams for (Co)Free!Streams for (Co)Free!
Streams for (Co)Free!
John De Goes
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus 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 Future
John 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 PureScript
John 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 Analytics
John De Goes
 

More from John De Goes (20)

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

Recently uploaded

Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 

Recently uploaded (20)

Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 

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