[英]F# accumulating sequence of random numbers
I want to create a sequence of numbers where each number is the sum of all the numbers gone before it plus a random number. 我想创建一个数字序列,其中每个数字是它前面的所有数字加上一个随机数的总和。
I tried to do it like this: 我试着这样做:
let random = new System.Random()
let addRandom =
seq{let rec stepRandom acc =
let step = random.Next(0,10)
yield! acc+step //-----wont accept this
stepRandom (acc+step)
stepRandom 0 }
The problem is it won't accept the yield inside a recursive function. 问题是它不会接受递归函数内的yield。
I can see a solution with a mutable value for the accumulation, but how could this problem be solved in an idiomatic way? 我可以看到一个具有可变值积累的解决方案,但是如何以惯用的方式解决这个问题呢?
How about a different approach, using the lovely unfold
function: 使用可爱的unfold
功能,采用不同的方法怎么样:
let random = new System.Random()
let r() = random.Next(0, 10)
let s = Seq.unfold (fun acc -> Some(acc, acc+r())) (r())
Unfold creates a sequence from an initial state (in this case the first random number - second argument) and a generator function (first argument) that takes the previous state and produces (1) a new state (in this case the sum of the previous state plus the random) and (2) a new element in the sequence (the previous state). 展开会从初始状态 (在本例中为第一个随机数 - 第二个参数)和生成器函数 (第一个参数)创建一个序列,该函数采用先前的状态并生成(1)一个新状态(在这种情况下是前一个的总和) state加上随机的)和(2)序列中的新元素(前一个状态)。
If you align the sequence expression with the inner function, then it becomes a natural recursive function definition. 如果将序列表达式与内部函数对齐,则它将成为自然的递归函数定义。 Additionally, going by your description, you want to yield the accumulator (or the new sum), not the new random int. 另外,按照你的描述,你想要产生累加器(或新的和),而不是新的随机int。
let random = new System.Random()
let addRandom =
let rec stepRandom acc = seq{
let step = random.Next(0,10)
yield acc
yield! stepRandom (acc + step) }
stepRandom 0
Another option is to use Seq.initInfinite with Seq.scan : 另一个选择是使用Seq.initInfinite和Seq.scan :
let rand = System.Random()
let s = Seq.initInfinite (fun _ -> rand.Next(0, 10))
|> Seq.scan (+) 0
|> Seq.skip 1
seq { let rand = System.Random()
while true do
yield rand.Next(0, 10) }
|> Seq.scan (+) 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.