Skip to content

@ksmutny /gist:5008306
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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
Something went wrong with that request. Please try again.