I am trying to fill a list with random numbers and am having diffculty ge开发者_如何学运维tting the random number part. What I have right now prints out a random number 10 times, what I want is to print out 10 different random numbers
let a = (new System.Random()).Next(1, 1000)
let listOfSquares = [ for i in 1 .. 10->a]
printfn "%A" listOfSquares
any tips or suggestions?
Your code is simply getting one random number and using it ten times.
This extension method might be useful:
type System.Random with
/// Generates an infinite sequence of random numbers within the given range.
member this.GetValues(minValue, maxValue) =
Seq.initInfinite (fun _ -> this.Next(minValue, maxValue))
Then you can use it like this:
let r = System.Random()
let nums = r.GetValues(1, 1000) |> Seq.take 10
let genRandomNumbers count =
let rnd = System.Random()
List.init count (fun _ -> rnd.Next ())
let l = genRandomNumbers 10
printfn "%A" l
When I write a random something dispenser I like to use the same random number generator for each call to the dispenser. You can do that in F# with closures (a combination of Joel's and ildjarn's answer).
Example:
let randomWord =
let R = System.Random()
fun n -> System.String [|for _ in 1..n -> R.Next(26) + 97 |> char|]
In this way, a single instance of Random is 'baked into' the function, reusing it with each call.
There are two problems:
1) In F# functions are supposed to be pure so a function without arguments is considered as final value.
To declare impure function "without arguments", let it take one argument of type unit
let a () = (new System.Random()).Next(1, 1000)
and call it passing unit argument
let list = [ for i in 1 .. 10 -> a () ]
Source
2) New System.Random()
instance is created each time when a
is called. This results in getting same numbers. To fix this, create the instance only once
let random = new System.Random()
let a () = random.Next(1, 1000)
let list = [ for i in 1 .. 10 -> a ()]
This isn't specific to F#, read explanation for C# for better understanding
You could also avoid declaring an impure function as said by Pavel and just run:
let rnd = Random()
let rndList = [for i in 0..100 do rnd.Next(1000)]
I think one should be careful how to initialize System.Random as it uses the current time as seed. One instance should be enough for the whole app. Injecting random into functions has the advantage that you can use a fixed seed and reproduce with semi randomness, e.g. for testing your logic.
let rnd = System.Random()
let genRandomNumbers random count =
List.init count (fun _ -> random.Next ())
let getRandomNumbersSeeded = getRandomNumbers rnd
let l = getRandomNumbersSeeded 10
printfn "%A" l
精彩评论