Skip to content

Instantly share code, notes, and snippets.

@joshuakfarrar
Last active July 6, 2018 22:26
Show Gist options
  • Save joshuakfarrar/9d3bd9aae50c3c777b7cb3ec137d8599 to your computer and use it in GitHub Desktop.
Save joshuakfarrar/9d3bd9aae50c3c777b7cb3ec137d8599 to your computer and use it in GitHub Desktop.
Implement FP in Scala exercise 6.11 using Cats' State Monad.
name := "candy-machine"
version := "0.1"
scalaVersion := "2.12.6"
scalacOptions += "-Ypartial-unification"
libraryDependencies += "org.typelevel" %% "cats-core" % "1.0.1"
import cats.data.State
sealed trait Input
case object Coin extends Input
case object Turn extends Input
case class Machine(locked: Boolean, candies: Int, coins: Int)
object Main extends App {
val insertCoin: State[Machine, (Boolean, Int)] = State(machine => {
machine.candies match {
case n if n > 0 => (machine, (false, machine.coins + 1))
case _ => (machine, (machine.locked, machine.coins))
}
})
val turn: State[Machine, (Boolean, Int)] = State(machine => {
machine.candies match {
case n if n > 0 => {
val candies = if (machine.locked) machine.candies else machine.candies - 1
(machine, (true, candies))
}
case _ => (machine, (machine.locked, machine.candies))
}
})
def act(input: Input): State[Machine, Machine] = State(machine => {
input match {
case Coin => {
val (locked, coins) = insertCoin.runA(machine).value
val m = machine.copy(locked = locked, coins = coins)
(m, m)
}
case Turn => {
val (locked, candies) = turn.runA(machine).value
val m = machine.copy(locked = locked, candies = candies)
(m, m)
}
}
})
def simulateMachine(actions: List[Input]): State[Machine, (Int, Int)] = State(machine => {
val m = actions.foldLeft(machine)((m, input) => act(input).runA(m).value)
(m, (m.coins, m.candies))
})
val actions = List[Input](
Coin,
Turn,
Turn,
Turn,
Turn,
Turn,
Coin,
Turn,
Turn,
Turn,
Turn,
Coin,
Coin,
Coin
)
val m = Machine(locked = true, candies = 5, coins = 10)
println(simulateMachine(actions).runA(m).value) // (15,3)!
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment