SlideShare une entreprise Scribd logo
1  sur  47
Télécharger pour lire hors ligne
Playing with the State Monad
David Galichet	

Freelance Developer
Twitter : @dgalichet
Let’s start with a simple problem
3
2
1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 0

(A, R, A, L, A, A)

2

Score : 0

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 1

(A, R, A, L, A, A)

2

Score : 0

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 1

(A, R, A, L, A, A)

2

Score : 0

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 1

(A, R, A, L, A, A)

2

Score : 0

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 1

(A, R, A, L, A, A)

2

Score : 0

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 1

(A, R, A, L, A, A)

2

Score : 0

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 1

(A, R, A, L, A, A)

2

Score : 1

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 2

(A, R, A, L, A, A)

2

Score : 1

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 2

(A, R, A, L, A, A)

2

Score : 1

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 2

(A, R, A, L, A, A)

2

Score : 1

1
0 R1 is blocked by R2 !
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 2

(A, R, A, L, A, A)

2

Score : 1

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 2

(A, R, A, L, A, A)

2

Score : 1

1
0
0

1

2

3
A simple simulation
R1

R2

3

(A, A, R, A, A, A)
Score : 2

(A, R, A, L, A, A)

2

Score : 1

1
0
0

1

2

3
The game rules
• We want to simulate two robots moving
through a nxm playground	

• Each robot can either turn on a direction
(North, South, East, West) or move one step
forward	

• Robots move or turn according to
instructions
The game rules
• A robot can’t go out of the playground	

• A robot will be blocked if another robot is on
the place	

• Some coins are spread on the playground	

• Robots gather coins when they move over it
Think about this game
• It appears that we will deal with many states
:	

• Playground with its coins	

• Robots with their positions and gathered
coins
We want functional purity
• Functional Purity has many advantages like
composability, idempotence, maintainability
and thread safety	

• We need to find a way to deal with states and
remain pure
Dealing with states
S => (S, A)
• S is the type of a state and A the type of a
computation	

• The outcome of this function is a new state
and a result
Chaining states computations
def chainStOps(!
c1: S => (S, A), !
c2: S => (S, A)!
): S => (S, A) = { s =>!
val (s1, _) = c1(s)!
c2(s1)!
}

Repeated many times, this can be error
prone !
Introducing State Monad
• The aim of the state monad is to abstract
over state manipulations
Introducing State Monad
trait State[S, +A] {!
def run(initial: S): (S, A)!
def map[B](f: A => B): State[S, B] = ???!
def flatMap[B](f: A => State[S, B]): State[S, B] = ???!
}!

!

object State {!
def apply[S, A](f: S => (S, A)): State[S, A] = ???!
}
Introducing State Monad
trait State[S, +A] {!
def run(initial: S): (S, A)!
def map[B](f: A => B): State[S, B] = ???!
def flatMap[B](f: A => State[S, B]): State[S, B] = ???!
}!

!

object State {!
def apply[S, A](f: S => (S, A)): State[S, A] = !
new State[S, A] {!
def run(initial: S): (S, A) = f(initial)!
}!
}
State Monad embed computation !
Introducing State Monad
trait State[S, +A] {!
def run(initial: S): (S, A)!

!

def map[B](f: A => B): State[S, B] = State { s =>!
val (s1, a) = run(s)!
(s1, f(a))!
}!
Don’t forget the definition:
!
State.apply(S => (S, A)): State[S,A]

!
!

def flatMap[B](f: A => State[S, B]): State[S, B] = ???!
}
Introducing State Monad
trait State[S, +A] {!
def run(initial: S): (S, A)!

!

def map[B](f: A => B): State[S, B] = State { s =>!
val (s1, a) = run(s)!
(s1, f(a))!
}!
Don’t forget the definition:
!
State.apply(S => (S, A)): State[S,A]

!
!

def flatMap[B](f: A => State[S, B]): State[S, B] =
State { s =>!
val (s1, a) = run(s)!
f(a).run(s1)!
}!
}
Coming back to our game !
• We drive robots using a list of instructions
sealed trait Instruction!
case object L extends Instruction // turn Left!
case object R extends Instruction // turn Right!
case object A extends Instruction // Go on
Coming back to our game !
• Each robot has a direction
sealed trait Direction {!
def turn(i: Instruction): Direction!
}!
case object North extends Direction {!
def turn(i: Instruction) = i match {!
case L => West!
case R => East!
case _ => this!
}!
}!
case object South extends Direction { ... }!
case object East extends Direction { ... }!
case object West extends Direction { ... }
Coming back to our game !
• A direction and a location define a position
case class Point(x: Int, y: Int)!

!

case class Position(point: Point, dir: Direction) {!
def move(s: Playground): Position = {!
val p1 = dir match {!
case North => copy(point = point.copy(y = point.y +
1))!
case South => ...!
}!
if (s.isPossiblePosition(p1)) p1 else this!
}!
def turn(instruction: Instruction): Position =
!
copy(direction = direction.turn(instruction))!
}
Coming back to our game !
• And each Robot is a player with a Score
sealed trait Player!
case object R1 extends Player!
case object R2 extends Player!

!

case class Score(player: Player, score: Int)
Coming back to our game !
• The state of each Robot is defined as :
case class Robot(!
player: Player, !
positions: List[Position], !
coins: List[Point] = Nil) {!
lazy val currentPosition = positions.head!

!
!

lazy val score = Score(player, coins.size)!

def addPosition(next: Position) = copy(positions =
next::positions)!

!

def addCoin(coin: Point) = copy(coins = coin::coins)!
}
Coming back to our game !
• Robots evolve in a playground :
case class Playground(!
bottomLeft: Point, topRight: Point, !
coins: Set[Point],!
r1: Robot, r2: Robot) {!

!
!
!
!

def isInPlayground(point: Point): Boolean =!
bottomLeft.x <= point.x && ...!
def isPossiblePosition(pos: Position): Boolean = ...!
lazy val scores = (r1.score, r2.score)!
def swapRobots(): Playground = copy(r1 = r2, r2 = r1)!

}
Look at what we did
• a set of Instructions,	

• a Position composed with Points and
Direction,	

• a definition for Players and Score,	

• a way to define Robot state	

• and a way to define Playground state
Let put these all together !
• Now, we need a method to process a single
instruction	

• And a method to process all instructions	

• The expected result is a State Monad that
will be run with the initial state of the
playground
Processing a single instruction
def processInstruction(i: Instruction)(s: Playground):
Playground = {!
val next = i match {!
case A => s.r1.currentPosition.move(s)!
case i => s.r1.currentPosition.turn(i)!
}!

!

if (s.coins.contains(next.point)) {!
s.copy(!
coins = s.coins - next.point, !
r1 = s.r1.addCoin(next.point).addPosition(next)!
)!
} else {!
s.copy(r1 = s.r1.addPosition(next))!
}!
}
Processing a single instruction
def processInstruction(i: Instruction)(s: Playground):
Playground = {!
val next = i match {!
case A => s.r1.currentPosition.move(s)!
case i => s.r1.currentPosition.turn(i)!
}!
We always process the robot on first position !

!

}

Robots will be swapped alternatively.
if (s.coins.contains(next.point)) {!
s.copy(!
coins = s.coins - next.point, !
r1 = s.r1.addCoin(next.point).addPosition(next)!
)!
} else {!
s.copy(r1 = s.r1.addPosition(next))!
}!
Quick reminder
trait State[S, +A] {!
def run(initial: S): (S, A)!
def map[B](f: A => B): State[S, B] = State { s =>!
val (s1, a) = run(s)!
(s1, f(a))!
}!
def flatMap[B](f: A => State[S, B]): State[S, B] =
State { s =>!
val (s1, a) = run(s)!
f(a).run(s1)!
}!
}!
object State {!
def apply[S, A](f: S => (S, A)): State[S, A] =!
new State[S, A] {!
def run(initial: S): (S, A) = f(initial)!
}!
}
Introducing new combinators
trait State[S, +A] {!
...!
}!
object State {!
def apply[S, A](f: S => (S, A)): State[S, A] =!
new State[S, A] {!
def run(initial: S): (S, A) = f(initial)!
}!

!

def get[S]: State[S, S] = State { s => (s, s) }!

!

def gets[S, A](f: S => A): State[S, A] = !
State { s => (s, f(s)) }!
}
Here comes the magic !
def compileInstructions(!
i1: List[Instruction], !
i2: List[Instruction]!
): State[Playground, (Score, Score)] = i1 match {!
case Nil if i2 == Nil => State.gets(_.scores)!
case Nil => State[Playground, (Score, Score)] { s =>
(s.swapRobots(), s.scores) !
}.flatMap { _ => compileInstructions(i2, i1) }!
case head::tail => State[Playground, (Score, Score)] !
{ s =>!
val s1 = processInstruction(head)(s)!
(s1.swapRobots(), s1.scores)!
}.flatMap { _ => compileInstructions(i2, tail) }!
}
Here comes the magic !
def compileInstructions(!
i1: List[Instruction], !
i2: List[Instruction]!
): State[Playground, (Score, Score)] = i1 match {!
case Nil if i2 == Nil => State.gets(_.scores)!
case Nil => State[Playground, (Score, Score)] { s =>
(s.swapRobots(), s.scores) !
}.flatMap { _ => compileInstructions(i2, i1) }!
case head::tail => State[Playground, (Score, Score)] !
{ s =>!
If both i1 and i2 are empty, we return a State
val s1 = processInstruction(head)(s)!
Monad with the run method implementation :
(s1.swapRobots(), s1.scores)!
s => (s, s.scores)!
}.flatMap { _ => compileInstructions(i2, tail) }!
This will return the Playground passed in argument
}
and the score as result.
Here comes the magic !
def compileInstructions(!
i1: List[Instruction], !
i2: List[Instruction]!
): State[Playground, (Score, Score)] = i1 match {!
case Nil if i2 == Nil => State.gets(_.scores)!
case Nil => State[Playground, (Score, Score)] { s =>
(s.swapRobots(), s.scores) !
}.flatMap { _ => compileInstructions(i2, Nil) }!
case head::tail => State[Playground, (Score, Score)] !
{ s =>!
val s1 = processInstruction(head)(s)!
(s1.swapRobots(), s1.scores)!
If i1 is empty, we return a State Monad with a
}.flatMap { _ that compileInstructions(i2, tail) }!
run method => swap robots in Playground
}
and returns scores.
Then we chain it with the processing of
instructions for the second list.
Here comes the magic !
We process
def compileInstructions(! i1 and return a new Playground where
robots are !
i1: List[Instruction],swapped.
Then we chain it with the processing of the instructions
i2: List[Instruction]!
i2 and tail of i1.
): State[Playground, of instructions are processed alternatively {!
Lists (Score, Score)] = i1 match !
case Nil if i2 == Nil => State.gets(_.scores)!
case Nil => State[Playground, (Score, Score)] { s =>
(s.swapRobots(), s.scores) !
}.flatMap { _ => compileInstructions(i2, i1) }!
case head::tail => State[Playground, (Score, Score)] !
{ s =>!
val s1 = processInstruction(head)(s)!
(s1.swapRobots(), s1.scores)!
}.flatMap { _ => compileInstructions(i2, tail) }!
}
Here comes the magic !
def compileInstructions(!
i1: List[Instruction], !
i2: List[Instruction]!
): State[Playground, (Score, Score)] = i1 match {!
case Nil if i2 == Nil => State.gets(_.scores)!
case Nil => State[Playground, (Score, Score)] { s =>
(s.swapRobots(), s.scores) !
}.flatMap { _ => compileInstructions(i2, i1) }!
case head::tail => State[Playground, (Score, Score)] !
{ s =>!
val s1 = processInstruction(head)(s)!
(s1.swapRobots(), s1.scores)!
}.flatMap { _ => compileInstructions(i2, tail) }!
}
Using for comprehensions
def getPositions(p: Playground): (Position, Position) =
(p.r1.currentPosition, p.r2.currentPosition)!

!

def enhanceResult(!
i1: List[Instruction], !
i2: List[Instruction]): State[Playground, (String,
(Position, Position))] = {!
for {!
scores <- compileInstructions(i1, i2)!
positions <- State.gets(getPositions)!
} yield (declareWinners(scores), positions)!
}
Conclusion
• State Monad simplify computations on states	

• Use it whenever you want to manipulate
states in a purely functional (parsing,
caching, validation ...)
To learn more about State Monad
• Functional programming in scala by Paul
Chiusano and Rúnar Bjarnason - This book is
awesome !	

• State Monad keynote by Michael Pilquist https://speakerdeck.com/mpilquist/scalazstate-monad	

• Learning scalaz by Eugene Yokota - http://
eed3si9n.com/learning-scalaz/State.html
Questions ?

Contenu connexe

Tendances

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
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type ClassesJohn De Goes
 
λ | Lenses
λ | Lensesλ | Lenses
λ | LensesOpen-IT
 
Scala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldWerner Hofstra
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
OSCON Presentation: Developing High Performance Websites and Modern Apps with...
OSCON Presentation: Developing High Performance Websites and Modern Apps with...OSCON Presentation: Developing High Performance Websites and Modern Apps with...
OSCON Presentation: Developing High Performance Websites and Modern Apps with...Doris Chen
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverseLuka Jacobowitz
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them AllJohn De Goes
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The WildStackMob Inc
 
Optics with monocle - Modeling the part and the whole
Optics with monocle - Modeling the part and the wholeOptics with monocle - Modeling the part and the whole
Optics with monocle - Modeling the part and the wholeIlan Godik
 
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
 
Type classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritanceType classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritanceAlexey Raga
 
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Philip Schwarz
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaDaniel Cukier
 
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
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }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
 

Tendances (20)

Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
λ | Lenses
λ | Lensesλ | Lenses
λ | Lenses
 
Scala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereld
 
Beyond Scala Lens
Beyond Scala LensBeyond Scala Lens
Beyond Scala Lens
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
OSCON Presentation: Developing High Performance Websites and Modern Apps with...
OSCON Presentation: Developing High Performance Websites and Modern Apps with...OSCON Presentation: Developing High Performance Websites and Modern Apps with...
OSCON Presentation: Developing High Performance Websites and Modern Apps with...
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
 
One Monad to Rule Them All
One Monad to Rule Them AllOne Monad to Rule Them All
One Monad to Rule Them All
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
 
Optics with monocle - Modeling the part and the whole
Optics with monocle - Modeling the part and the wholeOptics with monocle - Modeling the part and the whole
Optics with monocle - Modeling the part and the whole
 
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
 
Type classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritanceType classes 101 - classification beyond inheritance
Type classes 101 - classification beyond inheritance
 
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
Side by Side - Scala and Java Adaptations of Martin Fowler’s Javascript Refac...
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with 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
 
Atomically { Delete Your Actors }
Atomically { Delete Your Actors }Atomically { Delete Your Actors }
Atomically { Delete Your Actors }
 
Scala intro workshop
Scala intro workshopScala intro workshop
Scala intro workshop
 
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...
 

En vedette

Type class polymorphism
Type class polymorphismType class polymorphism
Type class polymorphismMayank Bairagi
 
Building a Functional Stream in Scala
Building a Functional Stream in ScalaBuilding a Functional Stream in Scala
Building a Functional Stream in ScalaDerek Wyatt
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3Kwang Yul Seo
 
mjprof: Monadic approach for JVM profiling
mjprof: Monadic approach for JVM profilingmjprof: Monadic approach for JVM profiling
mjprof: Monadic approach for JVM profilingHaim Yadid
 
(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to MonadsLawrence Evans
 
Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskellgoncharenko
 
전자책산업동향과 서비스 모델 (Slide Share)
전자책산업동향과 서비스 모델 (Slide Share)전자책산업동향과 서비스 모델 (Slide Share)
전자책산업동향과 서비스 모델 (Slide Share)Joong Ho Lee
 
The Eff monad, one monad to rule them all
The Eff monad, one monad to rule them allThe Eff monad, one monad to rule them all
The Eff monad, one monad to rule them allEric Torreborre
 
Dr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterDr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterScott Wlaschin
 
Real-World Functional Programming @ Incubaid
Real-World Functional Programming @ IncubaidReal-World Functional Programming @ Incubaid
Real-World Functional Programming @ IncubaidNicolas Trangez
 
Haskell study 15
Haskell study 15Haskell study 15
Haskell study 15Nam Hyeonuk
 
Real world akka recepies v3
Real world akka recepies v3Real world akka recepies v3
Real world akka recepies v3shinolajla
 
Functional Programming in C# and F#
Functional Programming in C# and F#Functional Programming in C# and F#
Functional Programming in C# and F#Alfonso Garcia-Caro
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monadskenbot
 
Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeScott Wlaschin
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
 
Les évolutions adaptatives
Les évolutions adaptativesLes évolutions adaptatives
Les évolutions adaptativesRESPONSIV
 
The Coming Intelligent Digital Assistant Era and Its Impact on Online Platforms
The Coming Intelligent Digital Assistant Era and Its Impact on Online PlatformsThe Coming Intelligent Digital Assistant Era and Its Impact on Online Platforms
The Coming Intelligent Digital Assistant Era and Its Impact on Online PlatformsCognizant
 

En vedette (20)

Type class polymorphism
Type class polymorphismType class polymorphism
Type class polymorphism
 
Building a Functional Stream in Scala
Building a Functional Stream in ScalaBuilding a Functional Stream in Scala
Building a Functional Stream in Scala
 
하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3하스켈 프로그래밍 입문 3
하스켈 프로그래밍 입문 3
 
mjprof: Monadic approach for JVM profiling
mjprof: Monadic approach for JVM profilingmjprof: Monadic approach for JVM profiling
mjprof: Monadic approach for JVM profiling
 
(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads(2015 06-16) Three Approaches to Monads
(2015 06-16) Three Approaches to Monads
 
Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskell
 
전자책산업동향과 서비스 모델 (Slide Share)
전자책산업동향과 서비스 모델 (Slide Share)전자책산업동향과 서비스 모델 (Slide Share)
전자책산업동향과 서비스 모델 (Slide Share)
 
Pratical eff
Pratical effPratical eff
Pratical eff
 
The Eff monad, one monad to rule them all
The Eff monad, one monad to rule them allThe Eff monad, one monad to rule them all
The Eff monad, one monad to rule them all
 
Dr Frankenfunctor and the Monadster
Dr Frankenfunctor and the MonadsterDr Frankenfunctor and the Monadster
Dr Frankenfunctor and the Monadster
 
Real-World Functional Programming @ Incubaid
Real-World Functional Programming @ IncubaidReal-World Functional Programming @ Incubaid
Real-World Functional Programming @ Incubaid
 
Haskell study 15
Haskell study 15Haskell study 15
Haskell study 15
 
Real world akka recepies v3
Real world akka recepies v3Real world akka recepies v3
Real world akka recepies v3
 
Functional Programming in C# and F#
Functional Programming in C# and F#Functional Programming in C# and F#
Functional Programming in C# and F#
 
Running Free with the Monads
Running Free with the MonadsRunning Free with the Monads
Running Free with the Monads
 
Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-Toe
 
The monad fear
The monad fearThe monad fear
The monad fear
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
Les évolutions adaptatives
Les évolutions adaptativesLes évolutions adaptatives
Les évolutions adaptatives
 
The Coming Intelligent Digital Assistant Era and Its Impact on Online Platforms
The Coming Intelligent Digital Assistant Era and Its Impact on Online PlatformsThe Coming Intelligent Digital Assistant Era and Its Impact on Online Platforms
The Coming Intelligent Digital Assistant Era and Its Impact on Online Platforms
 

Similaire à Playing with State Monad

F# at GameSys
F# at GameSysF# at GameSys
F# at GameSysYan Cui
 
F# in the Real World (DDD EA)
F# in the Real World (DDD EA)F# in the Real World (DDD EA)
F# in the Real World (DDD EA)Yan Cui
 
Adventures In Data Compilation
Adventures In Data CompilationAdventures In Data Compilation
Adventures In Data CompilationNaughty Dog
 
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPSend + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPFilippo Vitale
 
The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212Mahmoud Samir Fayed
 
Scaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of ScalazScaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of ScalazHeiko Seeberger
 
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptxACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptxssuser1eba67
 
PUSH DOWN AUTOMATA VS TURING MACHINE
PUSH DOWN AUTOMATA VS TURING MACHINEPUSH DOWN AUTOMATA VS TURING MACHINE
PUSH DOWN AUTOMATA VS TURING MACHINEAbhishek Shivhare
 
12IRGeneration.pdf
12IRGeneration.pdf12IRGeneration.pdf
12IRGeneration.pdfSHUJEHASSAN
 
Scala kansai summit-2016
Scala kansai summit-2016Scala kansai summit-2016
Scala kansai summit-2016Naoki Kitora
 
Brief tour of psp-std
Brief tour of psp-stdBrief tour of psp-std
Brief tour of psp-stdPaul Phillips
 
Stateモナドの解説 後編
Stateモナドの解説 後編Stateモナドの解説 後編
Stateモナドの解説 後編Masahiro Honma
 
ScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyGautam Rege
 
lalr. fo engineering student those who to
lalr. fo engineering student those who tolalr. fo engineering student those who to
lalr. fo engineering student those who toHjJordTzong
 
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5Doris Chen
 
AI - Introduction to Markov Principles
AI - Introduction to Markov PrinciplesAI - Introduction to Markov Principles
AI - Introduction to Markov PrinciplesAndrew Ferlitsch
 
Help with root locus homework1
Help with root locus homework1Help with root locus homework1
Help with root locus homework1Assignmentpedia
 

Similaire à Playing with State Monad (20)

F# at GameSys
F# at GameSysF# at GameSys
F# at GameSys
 
F# in the Real World (DDD EA)
F# in the Real World (DDD EA)F# in the Real World (DDD EA)
F# in the Real World (DDD EA)
 
Ch4b
Ch4bCh4b
Ch4b
 
Provenance Games
Provenance GamesProvenance Games
Provenance Games
 
Adventures In Data Compilation
Adventures In Data CompilationAdventures In Data Compilation
Adventures In Data Compilation
 
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSPSend + More = Money – Let’s mash 2 monads to solve a simple CSP
Send + More = Money – Let’s mash 2 monads to solve a simple CSP
 
The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212The Ring programming language version 1.10 book - Part 71 of 212
The Ring programming language version 1.10 book - Part 71 of 212
 
Scaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of ScalazScaladays 2011 - The Ease of Scalaz
Scaladays 2011 - The Ease of Scalaz
 
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptxACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
ACI-Webinar-3-MinMaxAlphaBetaPruning-TicTacToe.pptx
 
PUSH DOWN AUTOMATA VS TURING MACHINE
PUSH DOWN AUTOMATA VS TURING MACHINEPUSH DOWN AUTOMATA VS TURING MACHINE
PUSH DOWN AUTOMATA VS TURING MACHINE
 
12IRGeneration.pdf
12IRGeneration.pdf12IRGeneration.pdf
12IRGeneration.pdf
 
Scala kansai summit-2016
Scala kansai summit-2016Scala kansai summit-2016
Scala kansai summit-2016
 
Brief tour of psp-std
Brief tour of psp-stdBrief tour of psp-std
Brief tour of psp-std
 
Stateモナドの解説 後編
Stateモナドの解説 後編Stateモナドの解説 後編
Stateモナドの解説 後編
 
ScotRuby - Dark side of ruby
ScotRuby - Dark side of rubyScotRuby - Dark side of ruby
ScotRuby - Dark side of ruby
 
Deep RL.pdf
Deep RL.pdfDeep RL.pdf
Deep RL.pdf
 
lalr. fo engineering student those who to
lalr. fo engineering student those who tolalr. fo engineering student those who to
lalr. fo engineering student those who to
 
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
 
AI - Introduction to Markov Principles
AI - Introduction to Markov PrinciplesAI - Introduction to Markov Principles
AI - Introduction to Markov Principles
 
Help with root locus homework1
Help with root locus homework1Help with root locus homework1
Help with root locus homework1
 

Dernier

Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 

Dernier (20)

Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 

Playing with State Monad

  • 1. Playing with the State Monad David Galichet Freelance Developer Twitter : @dgalichet
  • 2. Let’s start with a simple problem 3 2 1 0 0 1 2 3
  • 3. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 0 (A, R, A, L, A, A) 2 Score : 0 1 0 0 1 2 3
  • 4. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 1 (A, R, A, L, A, A) 2 Score : 0 1 0 0 1 2 3
  • 5. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 1 (A, R, A, L, A, A) 2 Score : 0 1 0 0 1 2 3
  • 6. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 1 (A, R, A, L, A, A) 2 Score : 0 1 0 0 1 2 3
  • 7. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 1 (A, R, A, L, A, A) 2 Score : 0 1 0 0 1 2 3
  • 8. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 1 (A, R, A, L, A, A) 2 Score : 0 1 0 0 1 2 3
  • 9. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 1 (A, R, A, L, A, A) 2 Score : 1 1 0 0 1 2 3
  • 10. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 2 (A, R, A, L, A, A) 2 Score : 1 1 0 0 1 2 3
  • 11. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 2 (A, R, A, L, A, A) 2 Score : 1 1 0 0 1 2 3
  • 12. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 2 (A, R, A, L, A, A) 2 Score : 1 1 0 R1 is blocked by R2 ! 0 1 2 3
  • 13. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 2 (A, R, A, L, A, A) 2 Score : 1 1 0 0 1 2 3
  • 14. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 2 (A, R, A, L, A, A) 2 Score : 1 1 0 0 1 2 3
  • 15. A simple simulation R1 R2 3 (A, A, R, A, A, A) Score : 2 (A, R, A, L, A, A) 2 Score : 1 1 0 0 1 2 3
  • 16. The game rules • We want to simulate two robots moving through a nxm playground • Each robot can either turn on a direction (North, South, East, West) or move one step forward • Robots move or turn according to instructions
  • 17. The game rules • A robot can’t go out of the playground • A robot will be blocked if another robot is on the place • Some coins are spread on the playground • Robots gather coins when they move over it
  • 18. Think about this game • It appears that we will deal with many states : • Playground with its coins • Robots with their positions and gathered coins
  • 19. We want functional purity • Functional Purity has many advantages like composability, idempotence, maintainability and thread safety • We need to find a way to deal with states and remain pure
  • 20. Dealing with states S => (S, A) • S is the type of a state and A the type of a computation • The outcome of this function is a new state and a result
  • 21. Chaining states computations def chainStOps(! c1: S => (S, A), ! c2: S => (S, A)! ): S => (S, A) = { s =>! val (s1, _) = c1(s)! c2(s1)! } Repeated many times, this can be error prone !
  • 22. Introducing State Monad • The aim of the state monad is to abstract over state manipulations
  • 23. Introducing State Monad trait State[S, +A] {! def run(initial: S): (S, A)! def map[B](f: A => B): State[S, B] = ???! def flatMap[B](f: A => State[S, B]): State[S, B] = ???! }! ! object State {! def apply[S, A](f: S => (S, A)): State[S, A] = ???! }
  • 24. Introducing State Monad trait State[S, +A] {! def run(initial: S): (S, A)! def map[B](f: A => B): State[S, B] = ???! def flatMap[B](f: A => State[S, B]): State[S, B] = ???! }! ! object State {! def apply[S, A](f: S => (S, A)): State[S, A] = ! new State[S, A] {! def run(initial: S): (S, A) = f(initial)! }! } State Monad embed computation !
  • 25. Introducing State Monad trait State[S, +A] {! def run(initial: S): (S, A)! ! def map[B](f: A => B): State[S, B] = State { s =>! val (s1, a) = run(s)! (s1, f(a))! }! Don’t forget the definition: ! State.apply(S => (S, A)): State[S,A] ! ! def flatMap[B](f: A => State[S, B]): State[S, B] = ???! }
  • 26. Introducing State Monad trait State[S, +A] {! def run(initial: S): (S, A)! ! def map[B](f: A => B): State[S, B] = State { s =>! val (s1, a) = run(s)! (s1, f(a))! }! Don’t forget the definition: ! State.apply(S => (S, A)): State[S,A] ! ! def flatMap[B](f: A => State[S, B]): State[S, B] = State { s =>! val (s1, a) = run(s)! f(a).run(s1)! }! }
  • 27. Coming back to our game ! • We drive robots using a list of instructions sealed trait Instruction! case object L extends Instruction // turn Left! case object R extends Instruction // turn Right! case object A extends Instruction // Go on
  • 28. Coming back to our game ! • Each robot has a direction sealed trait Direction {! def turn(i: Instruction): Direction! }! case object North extends Direction {! def turn(i: Instruction) = i match {! case L => West! case R => East! case _ => this! }! }! case object South extends Direction { ... }! case object East extends Direction { ... }! case object West extends Direction { ... }
  • 29. Coming back to our game ! • A direction and a location define a position case class Point(x: Int, y: Int)! ! case class Position(point: Point, dir: Direction) {! def move(s: Playground): Position = {! val p1 = dir match {! case North => copy(point = point.copy(y = point.y + 1))! case South => ...! }! if (s.isPossiblePosition(p1)) p1 else this! }! def turn(instruction: Instruction): Position = ! copy(direction = direction.turn(instruction))! }
  • 30. Coming back to our game ! • And each Robot is a player with a Score sealed trait Player! case object R1 extends Player! case object R2 extends Player! ! case class Score(player: Player, score: Int)
  • 31. Coming back to our game ! • The state of each Robot is defined as : case class Robot(! player: Player, ! positions: List[Position], ! coins: List[Point] = Nil) {! lazy val currentPosition = positions.head! ! ! lazy val score = Score(player, coins.size)! def addPosition(next: Position) = copy(positions = next::positions)! ! def addCoin(coin: Point) = copy(coins = coin::coins)! }
  • 32. Coming back to our game ! • Robots evolve in a playground : case class Playground(! bottomLeft: Point, topRight: Point, ! coins: Set[Point],! r1: Robot, r2: Robot) {! ! ! ! ! def isInPlayground(point: Point): Boolean =! bottomLeft.x <= point.x && ...! def isPossiblePosition(pos: Position): Boolean = ...! lazy val scores = (r1.score, r2.score)! def swapRobots(): Playground = copy(r1 = r2, r2 = r1)! }
  • 33. Look at what we did • a set of Instructions, • a Position composed with Points and Direction, • a definition for Players and Score, • a way to define Robot state • and a way to define Playground state
  • 34. Let put these all together ! • Now, we need a method to process a single instruction • And a method to process all instructions • The expected result is a State Monad that will be run with the initial state of the playground
  • 35. Processing a single instruction def processInstruction(i: Instruction)(s: Playground): Playground = {! val next = i match {! case A => s.r1.currentPosition.move(s)! case i => s.r1.currentPosition.turn(i)! }! ! if (s.coins.contains(next.point)) {! s.copy(! coins = s.coins - next.point, ! r1 = s.r1.addCoin(next.point).addPosition(next)! )! } else {! s.copy(r1 = s.r1.addPosition(next))! }! }
  • 36. Processing a single instruction def processInstruction(i: Instruction)(s: Playground): Playground = {! val next = i match {! case A => s.r1.currentPosition.move(s)! case i => s.r1.currentPosition.turn(i)! }! We always process the robot on first position ! ! } Robots will be swapped alternatively. if (s.coins.contains(next.point)) {! s.copy(! coins = s.coins - next.point, ! r1 = s.r1.addCoin(next.point).addPosition(next)! )! } else {! s.copy(r1 = s.r1.addPosition(next))! }!
  • 37. Quick reminder trait State[S, +A] {! def run(initial: S): (S, A)! def map[B](f: A => B): State[S, B] = State { s =>! val (s1, a) = run(s)! (s1, f(a))! }! def flatMap[B](f: A => State[S, B]): State[S, B] = State { s =>! val (s1, a) = run(s)! f(a).run(s1)! }! }! object State {! def apply[S, A](f: S => (S, A)): State[S, A] =! new State[S, A] {! def run(initial: S): (S, A) = f(initial)! }! }
  • 38. Introducing new combinators trait State[S, +A] {! ...! }! object State {! def apply[S, A](f: S => (S, A)): State[S, A] =! new State[S, A] {! def run(initial: S): (S, A) = f(initial)! }! ! def get[S]: State[S, S] = State { s => (s, s) }! ! def gets[S, A](f: S => A): State[S, A] = ! State { s => (s, f(s)) }! }
  • 39. Here comes the magic ! def compileInstructions(! i1: List[Instruction], ! i2: List[Instruction]! ): State[Playground, (Score, Score)] = i1 match {! case Nil if i2 == Nil => State.gets(_.scores)! case Nil => State[Playground, (Score, Score)] { s => (s.swapRobots(), s.scores) ! }.flatMap { _ => compileInstructions(i2, i1) }! case head::tail => State[Playground, (Score, Score)] ! { s =>! val s1 = processInstruction(head)(s)! (s1.swapRobots(), s1.scores)! }.flatMap { _ => compileInstructions(i2, tail) }! }
  • 40. Here comes the magic ! def compileInstructions(! i1: List[Instruction], ! i2: List[Instruction]! ): State[Playground, (Score, Score)] = i1 match {! case Nil if i2 == Nil => State.gets(_.scores)! case Nil => State[Playground, (Score, Score)] { s => (s.swapRobots(), s.scores) ! }.flatMap { _ => compileInstructions(i2, i1) }! case head::tail => State[Playground, (Score, Score)] ! { s =>! If both i1 and i2 are empty, we return a State val s1 = processInstruction(head)(s)! Monad with the run method implementation : (s1.swapRobots(), s1.scores)! s => (s, s.scores)! }.flatMap { _ => compileInstructions(i2, tail) }! This will return the Playground passed in argument } and the score as result.
  • 41. Here comes the magic ! def compileInstructions(! i1: List[Instruction], ! i2: List[Instruction]! ): State[Playground, (Score, Score)] = i1 match {! case Nil if i2 == Nil => State.gets(_.scores)! case Nil => State[Playground, (Score, Score)] { s => (s.swapRobots(), s.scores) ! }.flatMap { _ => compileInstructions(i2, Nil) }! case head::tail => State[Playground, (Score, Score)] ! { s =>! val s1 = processInstruction(head)(s)! (s1.swapRobots(), s1.scores)! If i1 is empty, we return a State Monad with a }.flatMap { _ that compileInstructions(i2, tail) }! run method => swap robots in Playground } and returns scores. Then we chain it with the processing of instructions for the second list.
  • 42. Here comes the magic ! We process def compileInstructions(! i1 and return a new Playground where robots are ! i1: List[Instruction],swapped. Then we chain it with the processing of the instructions i2: List[Instruction]! i2 and tail of i1. ): State[Playground, of instructions are processed alternatively {! Lists (Score, Score)] = i1 match ! case Nil if i2 == Nil => State.gets(_.scores)! case Nil => State[Playground, (Score, Score)] { s => (s.swapRobots(), s.scores) ! }.flatMap { _ => compileInstructions(i2, i1) }! case head::tail => State[Playground, (Score, Score)] ! { s =>! val s1 = processInstruction(head)(s)! (s1.swapRobots(), s1.scores)! }.flatMap { _ => compileInstructions(i2, tail) }! }
  • 43. Here comes the magic ! def compileInstructions(! i1: List[Instruction], ! i2: List[Instruction]! ): State[Playground, (Score, Score)] = i1 match {! case Nil if i2 == Nil => State.gets(_.scores)! case Nil => State[Playground, (Score, Score)] { s => (s.swapRobots(), s.scores) ! }.flatMap { _ => compileInstructions(i2, i1) }! case head::tail => State[Playground, (Score, Score)] ! { s =>! val s1 = processInstruction(head)(s)! (s1.swapRobots(), s1.scores)! }.flatMap { _ => compileInstructions(i2, tail) }! }
  • 44. Using for comprehensions def getPositions(p: Playground): (Position, Position) = (p.r1.currentPosition, p.r2.currentPosition)! ! def enhanceResult(! i1: List[Instruction], ! i2: List[Instruction]): State[Playground, (String, (Position, Position))] = {! for {! scores <- compileInstructions(i1, i2)! positions <- State.gets(getPositions)! } yield (declareWinners(scores), positions)! }
  • 45. Conclusion • State Monad simplify computations on states • Use it whenever you want to manipulate states in a purely functional (parsing, caching, validation ...)
  • 46. To learn more about State Monad • Functional programming in scala by Paul Chiusano and Rúnar Bjarnason - This book is awesome ! • State Monad keynote by Michael Pilquist https://speakerdeck.com/mpilquist/scalazstate-monad • Learning scalaz by Eugene Yokota - http:// eed3si9n.com/learning-scalaz/State.html