简体   繁体   中英

Closures and random numbers in F#

For fun, I am trying to write a simple simulation of the Monty Hall problem problem using F#.

I have created a function getShow which returns an array of three booleans (representing doors), one of which is randomly true (it has a car behind it) and the other two false.

let getShow = 
    let doorWithCar = System.Random().Next(3)+1
    [|for door in 1..3 -> door = doorWithCar|]

Now when I try to get a sequence of shows using yield to call the getShow function, I keep getting the first random show repeated (I am guessing because of the way closures work in F#).

let shows = 
  seq { for i in 1 .. 10 do yield getShow} // Keeps generating the same show over and over

What is the correct way to call the getShow function using yield so that it actually calls the function and gets a new random array?

getShow is a value and not a function, so it's calculated once and you keep yielding the same value. To turn it into a function you have to add () . Also, you keep creating a new Random instance, which is probably initialized with the same time seed, not giving you what you want. Try this instead:

let random = System.Random()
let getShow() = 
    let doorWithCar = random.Next(3)+1
    [|for door in 1..3 -> door = doorWithCar|]
let shows = 
   seq { for i in 1 .. 10 do yield getShow()}

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.

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