2014-03-13 46 views
2

我想要创建一个数字序列,其中每个数字是之前所有数字加上一个随机数的总和。F#累积随机数序列

我试图做这样的:

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 } 

问题是,它不会接受一个递归函数里面的产量。

我可以看到一个具有可变值的解决方案,但如何以一种习惯方式解决这个问题?

回答

4

如果将序列表达式与内部函数对齐,则它将成为自然递归函数定义。另外,按照你的描述,你想要产生累加器(或新的总和),而不是新的随机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 
+0

是的,谢谢,我已经纠正了错误。 –

5

如何不同的方法,使用可爱unfold功能:

let random = new System.Random() 
let r() = random.Next(0, 10) 
let s = Seq.unfold (fun acc -> Some(acc, acc+r())) (r()) 

展开创建从初始状态一个序列(在这种情况下,第一个随机数 - 第二个参数)和生成器函数(第一个参数),它取前一个状态并产生(1)一个新状态(在这种情况下是前一个状态加上随机的和)和(2)序列中的一个新元素(前一个状态) 。

3

另一种选择是使用Seq.initInfiniteSeq.scan

let rand = System.Random() 
let s = Seq.initInfinite (fun _ -> rand.Next(0, 10)) 
    |> Seq.scan (+) 0 
    |> Seq.skip 1 
+1

我也是这么做的。但是,之后我会将它传给'Seq.skip 1',以摆脱领先的'0'。 – torbonde

+1

好点,我已更改代码以符合您的建议。 – mattnewport

3
seq { let rand = System.Random() 
     while true do 
     yield rand.Next(0, 10) } 
|> Seq.scan (+) 0