2016-01-26 3 views
4

Стандартная библиотека Elm предлагает a function to generate random lists, который отлично работает. . Посмотрев на its implementation, мы видим, что список построен в функциональном стиле, то есть от конца до начала. Когда достаточное количество элементов были получено, то обращенный список возвращается:Внедрение случайного списка Elm

if n < 1 then 
    (List.reverse list, seed) 

Я задаюсь вопросом, почему мы должны полностью изменить этот список? Нужно ли обеспечить «правильную» случайность?

+0

, потому что мы можем предварять одно значение в список, и мы можем только добавить список в список. Так что это всего лишь вопрос реализации http://package.elm-lang.org/packages/elm-lang/core/latest/List – rofrol

ответ

3

Звонок List.reverse фактически возвращает список в том порядке, в котором он был сгенерирован.

Вот код для рассматриваемых функций:

list : Int -> Generator a -> Generator (List a) 
list n (Generator generate) = 
    Generator <| \seed -> 
    listHelp [] n generate seed 

listHelp : List a -> Int -> (Seed -> (a,Seed)) -> Seed -> (List a, Seed) 
listHelp list n generate seed = 
    if n < 1 then 
    (List.reverse list, seed) 
    else 
    let 
     (value, newSeed) = 
     generate seed 
    in 
     listHelp (value :: list) (n-1) generate newSeed 

Если мы концептуально упростить понятие Seed к Int, и предположим, что у нас есть генератор, который возвращает (seed, seed + 1), вы можете рассуждать о итерации, как это, если наше первоначальное семя 1 (генерируя список из 5 элементов):

listHelp [] 5 myGen 1 -- initial state 
listHelp [1] 4 myGen 2 
listHelp [2,1] 3 myGen 3 
listHelp [3,2,1] 2 myGen 4 
listHelp [4,3,2,1] 1 myGen 5 
listHelp [5,4,3,2,1] 0 myGen 6 

окончательный список выходной затем обратный, чтобы дать вам [1,2,3,4,5].

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

Рассмотрим, если список был не вспять в этом последнем шаге (при условии initialSeed является 1).

List.head (list 5 (myGen initialSeed)) == Just 5 
List.head (list 4 (myGen initialSeed)) == Just 4 

Поскольку все эти псевдо-хаотичности требует Seed в качестве входных данных, он делает гораздо больше смысла рассуждать о вещах, на предсказуемой основе, а не вводить произвольное переупорядочивать, что бы сделать list непредсказуемы. List.reverse исправляет выход и возвращает его в область предсказуемости.

1

Возможно, потому что большинство случайных генераторов на самом деле не случайны. Если вы начинаете их с одного и того же семени, вы получаете одну и ту же последовательность. Если вы зависите от этого факта для тестирования, то повторение последовательности в обратном порядке может привести к нарушению вашего теста.

Предполагается, что большинство программистов ожидали бы, что сгенерированная последовательность будет в порядке списка, то есть первый элемент будет первым сгенерированным. Я думаю, что это вероятное предположение. Поэтому стоит обратить вспять список в конце, чтобы api был менее удивителен.

Смежные вопросы