I am trying to write a pseudo-random generator in Elm (to generate points on a screen) but not so easy since it interferes with the ``purity" of the Elm compiler.
OK, so why not write our own function? We can get sort-of random behavior if we write stuff like:
-- initial state
randomNumbers = [ 1 ]
x = 1
b = 2
n = 2017
-- generate random numbers
x = (x*b) % n
randomNumbers = x :: randomNumbers
This does not follow Elm's rule of variable assignments. Something is wrong.
All I am doing is finding the power of 2 mod 2017. The first few are easy but then the sequence gets unpredictible. So I need to keep track of the last number computed.
[ 1, 2, 4, 8, ... , 1024, 31, 62, 124, ...]
Even if I try to use special properties of arithmetic I still have to compute this sparse list of powers
[ 1, 2^1, 2^2, 2^4, 2^8, 2^16, ... ]
can I can solve by successive squaring, but I still need some way to memorize the last step.
I thought... as long as I write my own code, I don't have to import randomness from the "real world" to generate my fair numbers. This way respecting the pureness of Elm. However, I end up writing something that is stateful.
Elm does have a random-number generator now - an implementation of some algorithm - in the Random
library, returning a generator
type.
This repl session has been quite instructive:
> import Random exposing (..)
>
> initialSeed 0
Seed {
state = State 1 1 ,
next = <function>,
split = <function>,
range = <function>
}
: Random.Seed
> seed0 = initialSeed 101
Seed {
state = State 102 1, ,
next = <function>,
split = <function>,
range = <function>
}
: Random.Seed
> step ( int 0 10 ) seed0
(10,Seed { state = State 4081428 40692, ,
next = <function>,
split = <function>,
range = <function>
}
: ( Int, Random.Seed )
Even with my simplified baby random number generator, what is so stateful here?
My apologies in advance if I say memoizaton when I mean dynamic programming or the other way around
What is the difference between memoization and dynamic programming?
If I could write a stateful function f
that remembered things, I could generate all my values with just one line:
List.map f [1..100]