榆树标准库提供的a function to generate random lists工作正常。 通过查看its implementation,我们可以看到列表是以函数样式构建的,即从结尾到开头。生成足够的元素后,将返回反向列表:
if n < 1 then
(List.reverse list, seed)
我想知道为什么我们需要撤销此列表?是否有必要确保“正确”的随机性?
答案 0 :(得分: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个元素的列表):
1
然后反转最终输出列表,为您提供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
修复输出并将其重新置于可预测性范围内。
答案 1 :(得分:1)
可能是因为大多数随机发生器并非真正随机。如果使用相同的种子启动它们,则会得到相同的序列。如果你依赖这个事实进行测试,那么让序列以相反的顺序返回可能会破坏你的测试。
假设大多数程序员都希望生成的序列按列表顺序排列,即第一个项目将是第一个生成的。我认为这是一个可能的假设。所以值得在最后颠倒列表以便api不那么令人惊讶。
答案 2 :(得分:0)
因为我们可以将单个值添加到List,我们只能将List附加到List。我们可以
num
然后我们不必扭转它
http://package.elm-lang.org/packages/elm-lang/core/latest/List