public
Created

Functional Programming in Scala, chapter 6, created at London Scala User Group Coding Dojo, Feb 21, 2013

  • Download Gist
gistfile1.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
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))))
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.