Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

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

View gist:5008306
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))))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.