Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# getting a list of random numbers

Tags:

f#

I am trying to fill a list with random numbers and am having diffculty getting 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?

like image 378
Aaron Avatar asked May 19 '11 17:05

Aaron


4 Answers

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
like image 63
Joel Mueller Avatar answered Nov 12 '22 19:11

Joel Mueller


let genRandomNumbers count =
    let rnd = System.Random()
    List.init count (fun _ -> rnd.Next ())

let l = genRandomNumbers 10
printfn "%A" l
like image 22
ildjarn Avatar answered Nov 12 '22 21:11

ildjarn


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.

like image 32
cfern Avatar answered Nov 12 '22 21:11

cfern


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

like image 2
Pavel Avatar answered Nov 12 '22 20:11

Pavel