开发者

Force multiple evaluations of a function in F#

I am trying to develop a random number "generator" in F#.

I successfully created the following function:

let draw () =
    let rand = new Random()
    rand.Next(0,36)

This works fine and it generates a number between 0 and 36.

However, I am trying开发者_JAVA技巧 to create a function that runs this function several times.

I tried the following

let multipleDraws (n:int) =
    [for i in 1..n -> draw()]

However, I only get a single result, as draw is evaluated only once in the for comprehension.

How could I force multiple executions of the draw function?


The problem is with the Random type. It uses the computer's time to generate a seed and then generate the random numbers. Since practically the time of the calls is identical, the same seed is generated and so are also same numbers returned.

This will solve your problem:

let draw =
    let rand = new Random()
    fun () ->
    rand.Next(0,36)

And then:

let multipleDraws (n:int) =
    [for i in 1..n -> draw()]


Adding this to help explain Ramon's answer.

This code uses a lambda function.

let draw =
    let rand = new Random()
    fun () ->
    rand.Next(0,36)

It may be easier to understand what's happening if you give the lambda function a name.

let draw =
    let rand = new Random()
    let next() =
        rand.Next(0,36)
    next

The variable draw is being assigned the function next. You can move rand and next out of the scope of draw to see the assignment directly.

let rand = new Random()
let next() =
    rand.Next(0,36)
let draw = next

You can see from the above code that in Ramon's answer new Random is only called once while it is called many times in SRKX's example.

As mentioned by Ramon Random generates a sequence of numbers based on a random seed. It will always generate the same sequence of numbers if you use the same seed. You can pass random a seed like this new Random(2). If you do not pass it a value it uses the current time. So if you call new Random multiple times in a row without a seed it will most likely have the same seed (because the time hasn't changed). If the seed doesn't change then the first random number of the sequence will always be the same. If you try SRKX's original code and call multipleDraws with a large enough number, then the time will change during the loop and you will get back a sequence of numbers that changes every so often.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜