Skip to content

Instantly share code, notes, and snippets.

@non
Last active October 21, 2015 22:48
Show Gist options
  • Save non/99bab21d235fc3f5dff6 to your computer and use it in GitHub Desktop.
Save non/99bab21d235fc3f5dff6 to your computer and use it in GitHub Desktop.
package zg
import spire.random.Generator
/**
* ImGen is an immutable RNG.
*
* It "hides" Generator's mutability through next.
*/
class ImGen[G <: Generator](gen: G) {
def next[A](f: G => A): (ImGen[G], A) = {
val gen2 = gen.copy
val a = f(gen2)
(new ImGen(gen2), a)
}
def nextInt: (ImGen[G], Int) = next(_.nextInt)
// and so on...
}
// alternately, we can just allow any Generator to be wrapped
class ImGen2(gen: Generator) {
def next[A](f: Generator => A): (ImGen2, A) = {
val gen2 = gen.copy
val a = f(gen2)
(new ImGen2(gen2), a)
}
def nextInt: (ImGen2, Int) = next(_.nextInt)
// and so on...
}
@oxbowlakes
Copy link

  class ImGen[G <: Generator](gen: Generator) {
    def next[A](f: Generator => A): (ImGen[G], A) = {
      val gen2 = gen.copy
      val a = f(gen2)
      (new ImGen(gen2), a)
    }
    def nextInt: (ImGen[G], Int) = next(_.nextInt())

@non
Copy link
Author

non commented Oct 21, 2015

Thanks for the corrections! I just banged that out quickly without testing.

@oxbowlakes
Copy link

Thanks Erik - this was actually a drop-in replacement for the methods defined at these signatures (on the companion)

  object RNG {
    val monadState = StateT.stateTMonadState[RNG, Free.Trampoline]
    type State[A] = StateT[Free.Trampoline, RNG, A]

    def stateF[A](f: RNG => Free.Trampoline[(RNG, A)]): State[A] = StateT[Free.Trampoline, RNG, A](f)
    def nextDouble: State[Double] = stateF[Double](s => s.nextDouble.point[Free.Trampoline])
    def default: RNG = new RNG(Generator.rng)
    def apply(seed: Long): RNG = new RNG(Cmwc5.fromTime(seed))
  }
  class RNG private(gen: Generator) {
    def next[A](f: Generator => A): (RNG, A) = {
      val gen2 = gen.copy
      val a = f(gen2)
      (new RNG(gen2), a)
    }
    def nextDouble: (RNG, Double) = next(_.nextDouble())
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment