简体   繁体   中英

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.

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:

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).

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.

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 :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM