Skip to content

Instantly share code, notes, and snippets.

@seraphr seraphr/State.scala
Last active Aug 29, 2015

Embed
What would you like to do?
fp in scala EXERCISE 6.6 6.7 map2とsequenceの実装
trait RNG {
def nextInt: (Int, RNG)
}
object RNG {
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL // `&` is bitwise AND. We use the current seed to generate a new seed.
val nextRNG = Simple(newSeed) // The next state, which is an `RNG` instance created from the new seed.
val n = (newSeed >>> 16).toInt // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
(n, nextRNG) // The return value is a tuple containing both a pseudo-random integer and the next `RNG` state.
}
}
type Rand[+A] = RNG => (A, RNG)
val int: Rand[Int] = _.nextInt
def unit[A](a: A): Rand[A] = rng => (a, rng)
def map2[A,B,C](ra: Rand[A], rb: Rand[B])(f: (A, B) => C): Rand[C] = r => {
val (a, r1) = ra(r)
val (b, r2) = rb(r1)
(f(a, b), r2)
}
def sequence[A](fs: List[Rand[A]]): Rand[List[A]] = fs match {
case r :: rs => map2(r, sequence(rs))(_ :: _)
case _ => unit(List[A]())
}
def ints(count: Int)(rng: RNG): (List[Int], RNG) = sequence(List.fill(count)(int))(rng)
}
RNG.ints(5)(RNG.Simple(2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.