-
Notifications
You must be signed in to change notification settings - Fork 2
State Monad
Dinko Srkoč edited this page Aug 7, 2011
·
3 revisions
State monad may be used when there is a sequence of operations that depend on a shared state.
That state is then passed around and changed as needed. Monadic functions receive state and
should return a [state, result] tuple.
For example, let's show how to solve the game of Fizzbuzz using state monad.
We should print the numbers from 1 to 100, but replace every multiple of 3 with "Fizz", every multiple of 5 with "Buzz", and for numbers that are multiples of both 3 and 5 print "FizzBuzz".
import static hr.helix.monadologie.MonadComprehension.foreach
import static hr.helix.monadologie.monads.State.state
import static hr.helix.monadologie.monads.State.init
def fizz = { it % 3 ? "" : "Fizz" },
buzz = { it % 5 ? "" : "Buzz" }
def fizzbuzz = foreach {
a = takeFrom { init() }
b = takeFrom { state { s -> [fizz(a), a] }}
c = takeFrom { state { s -> [s + buzz(b), b] }}
yield { c }
}
(1..100).each {
def fb = fizzbuzz(it)
println fb[0] ?: fb[1]
}In the example from the What Is a Monad we're depositing and withdrawing amounts from
the account. The same functionality can be accomplished without Account monad:
import static hr.helix.monadologie.MonadComprehension.foreach
import static hr.helix.monadologie.monads.State.state
def withdraw = { amt -> state { s -> [s - amt, s] }},
deposit = { amt -> state { s -> [s + amt, s] }}
def acc = foreach {
amt1 = takeFrom { deposit 15 }
amt2 = takeFrom { withdraw 9 }
yield { amt2 }
}
assert acc(11)[0] == 11 + 15 - 9