Last active
August 29, 2015 14:24
-
-
Save seraphr/764fa58a17ed2647fe4d to your computer and use it in GitHub Desktop.
fp in scala EXERCISE 6.6 6.7 map2とsequenceの実装
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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