Pure functional Random number generator - State monad

倾然丶 夕夏残阳落幕 提交于 2019-12-04 06:52:17

That random generator RNG is pure functional, for the same inputs you get always the same outputs. The non-pure-functional part is left for the user of that API (you).

To use the RNG in a pure-functional way you have to initialize it always with the same initial value, but then you will always get the same sequence of numbers, which is not so useful.

Otherwise, you will have to rely the initialization of RNG to an external system (usually the wall-clock time) and so introducing side effects (bye pure functional).

val state0 = RNG.simple(System.currentTimeMillis)

val (rnd1, state1) = state0.nextInt
val (rnd2, state2) = state1.nextInt
val (rnd3, state3) = state2.nextInt

println(rnd1, rnd2, rnd3)

[EDIT]

Inspired by the answer of @Aivean, I created my version of randoms Stream:

def randoms: Stream[Int] = Stream.from(0)
  .scanLeft((0, RNG.simple(System.currentTimeMillis)))((st, _) => st._2.nextInt)
  .tail
  .map(_._1)

println(randoms.take(5).toList)
println(randoms.filter(_ > 0).take(3).toList)

In addition, your example nicely combines with Scala streams:

  def randStream(r: RNG): Stream[Int] = r.nextInt match {
    case (value, next) => value #:: randStream(next)
  }

  val rng = randStream(RNG.simple(123))
  println(rng.take(10).toList)
  println(rng.take(5).toList)

Can someone give a full example of pure functional random number generator in Scala and perhaps relate it to state Monad in general.

This is a purely functional RNG.

val state0 = RNG.simple(1234)
val (r1, state1) = state0.nextInt
val (r2, state2) = state1.nextInt
// etc.
val (x, _) = state1.nextInt
assert (x == r2)

A recursive function, derived from @Aivean Stream based function,

def rand(n: Int, r: RNG): List[Int] = { 
  if (n < 0) List() 
  else {
    val (value, next) = r.nextInt
    value :: rand(n-1, next) 
  }
}

To get 5 random values,

rand(5, RNG.simple(System.currentTimeMillis) )
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!