简体   繁体   English

F# 获取随机数列表

[英]F# getting a list of random numbers

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我现在打印出一个随机数 10 次,我想要的是打印出 10 个不同的随机数

   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).您可以在 F# 中使用闭包(Joel 和 ildjarn 的答案的组合)来做到这一点。

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.通过这种方式,Random 的单个实例被“烘焙”到函数中,并在每次调用时重用它。

There are two problems:有两个问题:

1) In F# functions are supposed to be pure so a function without arguments is considered as final value. 1) 在 F# 中,函数应该是函数,因此没有参数的函数被视为最终值。

To declare impure function "without arguments", let it take one argument of type unit要声明“不带参数”的不纯函数,请让它接受一个类型为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. 2) 每次调用a时都会创建新的System.Random()实例。 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这不是特定于 F#,阅读C# 的解释以更好地理解

You could also avoid declaring an impure function as said by Pavel and just run:你也可以避免像 Pavel 所说的那样声明一个不纯的函数,然后运行:

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.我认为应该小心如何初始化 System.Random 因为它使用当前时间作为种子。 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, eg 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM