Skip to content

Instantly share code, notes, and snippets.

@n4to4
Created September 7, 2016 21:43
Show Gist options
  • Save n4to4/5ed23fe8859fbacfa57d1f8f66158fbc to your computer and use it in GitHub Desktop.
Save n4to4/5ed23fe8859fbacfa57d1f8f66158fbc to your computer and use it in GitHub Desktop.
State examples from herding-cats
object St0 {
type Stack = List[Int]
def pop(s0: Stack): (Stack, Int) =
s0 match {
case x :: xs => (xs, x)
case Nil => sys.error("stack is empty")
}
def push(s0: Stack, a: Int): (Stack, Unit) =
(a :: s0, ())
def stackManip(s0: Stack): (Stack, Int) = {
val (s1, _) = push(s0, 3)
val (s2, a) = pop(s1)
pop(s2)
}
assert(stackManip(List(5, 8, 2, 1)) == (List(8, 2, 1), 5))
}
object St1 extends App {
import cats._, cats.data.State, cats.instances.all._
type Stack = List[Int]
// val pop = State[Stack, Int] {
// case x :: xs => (xs, x)
// case Nil => sys.error("stack is empty")
// }
val pop: State[Stack, Int] = for {
s <- State.get[Stack]
(x :: xs) = s
s <- State.set[Stack](xs)
} yield x
// def push(a: Int) = State[Stack, Unit] {
// xs => (a :: xs, ())
// }
def push(x: Int): State[Stack, Unit] = for {
xs <- State.get[Stack]
r <- State.set(x :: xs)
} yield r
def stackManip: State[Stack, Int] = for {
_ <- push(3)
a <- pop
b <- pop
} yield b
assert { stackManip.run(List(5, 8, 2, 1)).value == (List(8, 2, 1), 5) }
import cats.syntax.eq._
def stackyStack: State[Stack, Unit] = for {
stackNow <- State.get[Stack]
r <- if (stackNow === List(1, 2, 3)) State.set[Stack](List(8, 3, 1))
else State.set[Stack](List(9, 2, 1))
} yield r
assert { stackyStack.run(List(1, 2, 3)).value == (List(8, 3, 1), ()) }
assert { stackyStack.run(List(1, 2, 4)).value == (List(9, 2, 1), ()) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment