user3248346
user3248346

Reputation:

Generating random values

I'm getting stuck on generating some normally distributed random variables. I am using the mwc-random package.

In GHCI, I can do this:

gen <- create
normal 0 1 gen

and on my machine this produces:

-0.8077385934202513

In my program, I only want to create the generator once and then repeatedly use that to generate many random value for my simulation so I did this:

createGenerator :: PrimMonad m => m (Gen (PrimState m))                                              
createGenerator = do                                                                                 
  gen <- create                                                                                      
  return gen

returnPRNG :: PrimMonad m => Int -> Int -> m Double                                             
returnPRNG 0 1 =  normal 0 1 createGenerator 

But I get an error:

Couldn't match type ‘PrimState m’ with ‘Gen (PrimState Gen)’
 Expected type: Gen (PrimState m) 
   Actual type: Gen (Gen (PrimState Gen))

I'm probably not doing this idiomatically so any help in that area would be great also.

Upvotes: 0

Views: 62

Answers (1)

Random Dev
Random Dev

Reputation: 52280

When you want to create your generator only once than your the first part should look like this:

createGenerator :: PrimMonad m => m (Gen (PrimState m))
createGenerator = gen

...

main = do
    ...
    myGen <- createGenerator

(notice how you don't really do anything but give gen another name?)

and then you have to pass the generator around:

returnPRNG :: PrimMonad m => Double -> Double -> Gen (PrimState m) -> m Double
returnPRNG a b gen =  normal a b gen

which is of course just (again just another name)

returnPRNG = normal

(notice that you have to pass Doubles to normal - so assuming the extra arguments are really for that you have to use those)

the usage in your program will look like this:

main = do
    ...
    myGenen <- createGenerator
    ...
    rndVal1 <- returnPRNG 0 1 myGen
    rndVal2 <- returnPRNG 0 1 myGen

and as noticed that's really just

main = do
    ...
    myGen <- gen
    ...
    rndVal1 <- normal 0 1 myGen
    rndVal2 <- normal 0 1 myGen

Upvotes: 5

Related Questions