Принудительная множественная оценка функции в F # - PullRequest
5 голосов
/ 19 сентября 2011

Я пытаюсь разработать генератор случайных чисел в F #.

Я успешно создал следующую функцию:

let draw () =
    let rand = new Random()
    rand.Next(0,36)

Это прекрасно работает и генерирует число от 0 до 36.

Однако я пытаюсь создать функцию, которая запускает эту функцию несколько раз.

Я попробовал следующее

let multipleDraws (n:int) =
    [for i in 1..n -> draw()]

Однако, я получаю только один результат, так как draw оценивается только один раз для понимания.

Как я могу принудительно запустить несколько * draw функций?

Ответы [ 2 ]

8 голосов
/ 19 сентября 2011

Проблема с типом Random.Он использует время компьютера для генерации начального числа, а затем генерирует случайные числа.Поскольку практически время вызовов идентично, генерируется одинаковое начальное число, а также возвращаются одинаковые номера.

Это решит вашу проблему:

let draw =
    let rand = new Random()
    fun () ->
    rand.Next(0,36)

А затем:

let multipleDraws (n:int) =
    [for i in 1..n -> draw()]
6 голосов
/ 19 сентября 2011

Добавление этого, чтобы помочь объяснить ответ Рамона.

Этот код использует лямбда-функцию.

let draw =
    let rand = new Random()
    fun () ->
    rand.Next(0,36)

Может быть легче понять, что происходит, если вы дадите имя лямбда-функции.

let draw =
    let rand = new Random()
    let next() =
        rand.Next(0,36)
    next

Переменной draw назначается следующая функция. Вы можете переместить rand и next из области рисования, чтобы увидеть задание напрямую.

let rand = new Random()
let next() =
    rand.Next(0,36)
let draw = next

Из приведенного выше кода видно, что в ответе Рамона новый Random вызывается только один раз, тогда как в примере SRKX он вызывается много раз.

Как упомянул Рамон Рэндом, генерирует последовательность чисел на основе случайного начального числа. Он всегда будет генерировать одинаковую последовательность чисел, если вы используете одно и то же семя. Вы можете передать случайное семя, как это new Random(2). Если вы не передадите ему значение, оно использует текущее время. Поэтому, если вы вызываете new Random несколько раз подряд без начального числа, скорее всего, оно будет иметь одинаковое начальное значение (поскольку время не изменилось). Если начальное число не изменяется, то первое случайное число последовательности всегда будет одинаковым. Если вы попробуете исходный код SRKX и вызовете несколькоDraws с достаточно большим номером, то время будет меняться во время цикла, и вы будете возвращать последовательность чисел, которая меняется очень часто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...