Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Functional Programming in Scala, chapter 6, created at London Scala User Group Coding Dojo, Feb 21, 2013
import sun.reflect.generics.reflectiveObjects.NotImplementedException
object X extends App {
trait RNG {
def nextInt: (Int, RNG)
}
object RNG {
def simple(seed: Long): RNG = new RNG {
def nextInt = {
val seed2 = (seed*0x5DEECE66DL + 0xBL) &
((1L << 48) - 1)
((seed2 >>> 16).asInstanceOf[Int],
simple(seed2))
}
}
}
def positiveInt(rng: RNG): (Int, RNG) = {
val (n, newRng) = rng.nextInt
val pos = if (n == Int.MinValue) 0 else n.abs
(pos, newRng)
}
def positiveInt2(rng: RNG): (Int, RNG) = rng.nextInt match {
case (Int.MinValue, nextRng) => (0, nextRng)
case (n, nextRng) => (n.abs, nextRng)
}
def ints(count: Int)(rng: RNG): (List[Int], RNG) =
if (count <= 0) (Nil, rng)
else rng.nextInt match {
case (n, nextRng) =>
val (tail, nextRng2) = ints(count - 1)(nextRng)
(n :: tail, nextRng2)
}
type Rand[+A] = RNG => (A, RNG)
def map[A,B](s: Rand[A])(f: A => B): Rand[B] =
rng => {
val (a, rng2) = s(rng)
(f(a), rng2)
}
def positiveMax(n: Int): Rand[Int] = map(_.nextInt) { r => (r % n).abs }
val double: Rand[Double] = map(_.nextInt) { r => r.toDouble / Int.MaxValue }
def map2[A,B,C](ra: Rand[A], rb: Rand[B])(f: (A, B) => C): Rand[C] =
rng => {
val (a, rng2) = ra(rng)
val (b, rng3) = rb(rng2)
(f(a, b), rng3)
}
val intDouble: (RNG) => ((Int, Double), RNG) = map2(_.nextInt, double) { (_, _) }
val doubleInt = map2(double, _.nextInt) { (_, _) }
def sequence[A](fs: List[Rand[A]]): Rand[List[A]] = fs match {
case Nil => { rng => (Nil, rng) }
case head :: tail => { rng =>
val (a, interRng) = head(rng)
val (rest, nextRng) = sequence(tail)(interRng)
(a :: rest, nextRng)
}
}
def RngMock(nums: List[Int]): RNG = new RNG {
def nextInt = nums match {
case Nil => throw new NotImplementedException
case head :: tail => (head, RngMock(tail))
}
}
println(RNG.simple(4).nextInt)
println((Int.MinValue - 1).abs)
println(Int.MinValue.abs)
println(ints(10)(RngMock(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))))
println(positiveMax(100000)(RngMock(List(100010))))
println(sequence(List[Rand[Int]](_.nextInt, _.nextInt, _.nextInt))(RngMock(List(1, 4, 8))))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment