Skip to content

Instantly share code, notes, and snippets.

@JoolsF
Created March 12, 2019 09:45
Show Gist options
  • Save JoolsF/f7616014f6aa1b268fae2b209e9b43a6 to your computer and use it in GitHub Desktop.
Save JoolsF/f7616014f6aa1b268fae2b209e9b43a6 to your computer and use it in GitHub Desktop.
State Monad example 1
/**
* State Monad
* State[S,A] represents function of type S => (S , A)
* S is the state and A is the result
*/
import cats.data.State
val aState = State[Int, String] { state =>
val result = state * 2
(result, s"The result of step a is $result")
}
val bState = State[Int, String] { state =>
val result = state * 4
(result, s"The result of step b is $result")
}
val both = for {
ares <- aState
bres <- bState
} yield (ares, bres)
//Get the state and result
both.run(10).value // res0: (Int, (String, String)) = (80,(The result of step a is 20,The result of step b is 80))
//Get the state ignore the result
both.runS(10).value //res1: Int = 80
//Get the result ignore the state
both.runA(10).value //res2: (String, String) = (The result of step a is 20,The result of step b is 80)
//Updates state and returns unit as result
State.set[Int](10)
// Extracts state via transformation function
val inspectDemo = State.inspect[Int, String](_ + "!")
inspectDemo.run(10).value // res4: (Int, String) = (10,10!)
// Modify updates the state using a modify function
val modifyDemo = State.modify[Int](_ + 8)
modifyDemo.run(5).value // res5: (Int, Unit) = (13,())
import cats.data.State._
// Using a for comp. We would normally ignore the intermediate steps e.g a and b
val program: IndexedStateT[Eval, Int, Int, (Int, Int, Int)] = for {
a <- get[Int]
_ <- set[Int](a + 1)
b <- get[Int]
_ <- modify[Int](_ + 1)
c <- inspect[Int, Int](_ * 1000)
d <- inspect[Int, Int](_ * 1000)
} yield (a, b, c)
val (state, result) = program.run(1).value // result: (Int, Int, Int) = (1,2,4000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment