Instantly share code, notes, and snippets.

# ksmutny/gist:5008306 Created Feb 21, 2013

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)))) }