I have this funktion that chooses 4 randoms colors and makes a list of it. Atleast i want it too.:
let theList = [Red;Green;Yellow;Purple;White;Black]
let rec a x =
let rnd = System.Random()
match x with
|0 -> []
|_ -> (List.item(rnd.Next(6)) theList)::(a (x-1))
The problem is though it picks a random color every time i run the funktion then it always picks the same color for the entire list. [Red;Red;Red;Red] or [Green;Green;Green;Green] etc.
It is a mystery to me how it can arrive at the same color everytime it makes the recursive call.
If i use the random method in a for loop then no problem.
Can someone explain to me what is happening here?
Move your System.Random()
call out of the function and it will work. What you're doing is:
let rec a x =
let rnd = System.Random()
// ... Some code that calls rnd.Next() once, then recurses
Every time you recurse, you're creating a new System.Random
instance and assigning it to rnd
. That means that you're using the default constructor of System.Random
, and its documentation warns that:
... different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers.
What you really want is to create a single Random
instance, then use its .Next()
method repeatedly. One way would be to move the System.Random()
constructor call outside of the function:
let theList = [Red;Green;Yellow;Purple;White;Black]
let rnd = System.Random()
let rec a x =
match x with
|0 -> []
|_ -> (List.item(rnd.Next(6)) theList)::(a (x-1))
Another way, if you don't want to expose the rnd
name to outside code, would be to turn a
into an "inner" function that's nested inside an outer function (in the following example, doit
is the outer function):
let theList = [Red;Green;Yellow;Purple;White;Black]
let doit x =
let rnd = System.Random()
let rec a x =
match x with
|0 -> []
|_ -> (List.item(rnd.Next(6)) theList)::(a (x-1))
a x
Both of these should produce the truly random (well, pseudo-random) results that you're expecting.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.