Last active
December 17, 2015 18:48
-
-
Save tonymorris/5655357 to your computer and use it in GitHub Desktop.
How to produce random function values (Rng[B => A])?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed trait RngOp[A] { | |
def map[B](f: A => B): RngOp[B] = | |
this match { | |
case NextBits(b, n) => NextBits(b, f compose n) | |
case SetSeed(b, n) => SetSeed(b, () => f(n())) | |
} | |
def lift: Rng[A] = | |
Cont(map(Done(_))) | |
} | |
case class NextBits[A](b: Int, n: Int => A) extends RngOp[A] | |
case class SetSeed[A](b: Long, n: () => A) extends RngOp[A] | |
sealed trait Rng[A] { | |
def map[B](f: A => B): Rng[B] = | |
this match { | |
case Done(a) => Done(f(a)) | |
case Cont(r) => Cont(r map (_ map f)) | |
} | |
def flatMap[B](f: A => Rng[B]): Rng[B] = | |
this match { | |
case Done(a) => f(a) | |
case Cont(r) => Cont(r map (_ flatMap f)) | |
} | |
def function[B]: Rng[B => A] = | |
sys.error("what to do here?") | |
// Is Rng[A] => Rng[B => A] even sensible? | |
// What about other ways to produce Rng[B => A] values? | |
// map(a => _ => a) // ick! | |
// Can it be done with a constraint on B? | |
// such as Corng? | |
def functionAttemptWithCoRng[B](c: Corng[B]): Rng[B => A] = | |
sys.error("??") | |
} | |
case class Done[A](a: A) extends Rng[A] | |
case class Cont[A](r: RngOp[Rng[A]]) extends Rng[A] | |
object Rng { | |
def nextbits(n: Int): Rng[Int] = | |
NextBits(n, x => x).lift | |
def setseed(s: Long): Rng[Unit] = | |
SetSeed(s, () => ()).lift | |
def int: Rng[Int] = | |
nextbits(32) | |
def chooseint(l: Int, h: Int): Rng[Int] = | |
int map (x => { | |
val (ll, hh) = if(h < l) (h, l) else (l, h) | |
ll + math.abs(x % (hh - ll + 1)) | |
}) | |
def long: Rng[Long] = | |
for { | |
a <- nextbits(32) | |
b <- nextbits(32) | |
} yield (a.toLong << 32) + b | |
} | |
trait Corng[A] { | |
def run[B](a: A, r: Rng[B]): Rng[B] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment