Skip to content

Instantly share code, notes, and snippets.

@kkismd
Last active August 29, 2015 14:22
Show Gist options
  • Save kkismd/daaacdcf1e72da2c0812 to your computer and use it in GitHub Desktop.
Save kkismd/daaacdcf1e72da2c0812 to your computer and use it in GitHub Desktop.
my FP in Scalaz
package mystate
import scalaz._
import Scalaz._
case class RandGen(seed: Long) {
def nextInt: (RandGen, Int) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL
val nextGen = RandGen(newSeed)
val n = (newSeed >>> 16).toInt
(nextGen, n)
}
}
object Randz {
def unit(n: Int) = State[RandGen, Int](gen => (gen, n))
val int = State[RandGen,Int](_.nextInt)
val nonNegativeInt = int map Math.abs
val double = int map { _ / (Int.MaxValue.toDouble + 1) }
def nonNegativeLessThan(n: Int): State[RandGen, Int] = {
int flatMap { i =>
val mod = i % n
if (i + (n - 1) - mod >= 0)
unit(mod)
else
nonNegativeLessThan(n)
}
}
val rollDie = nonNegativeLessThan(6).map(_ + 1)
type Rand[A] = State[RandGen,A]
def ints(n: Int) = List.fill(n)(int).sequence[Rand,Int]
def example = {
for {
i <- int
j <- double
n <- nonNegativeLessThan(10)
l <- ints(3)
} yield (i, j, n, l)
}
}
sealed trait Input
case object Coin extends Input
case object Turn extends Input
case class Machine(locked: Boolean, candies: Int, coins: Int)
object Candy {
type Simulate[x] = State[Machine, x]
def simulateMachine(inputs: List[Input]): State[Machine, (Int, Int)] = {
def transit(i: Input, s: Machine): Machine = (i, s) match {
case (_, Machine(_, 0, _)) => s
case (Coin, Machine(false,_,_)) => s
case (Turn, Machine(true,_,_)) => s
case (Coin, Machine(true, ca, co)) => Machine(locked = false, ca, co + 1)
case (Turn, Machine(false, ca, co)) => Machine(locked = true, ca - 1, co)
}
for {
_ <- inputs.map(i => modify[Machine](s => transit(i, s))).sequence[Simulate,Unit]
s <- get
} yield (s.candies, s.coins)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment