Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# Is there a Async.Sequential to match Async.Parallel?

F# has Async.Parallel with type signature seq<Async<'a>> -> Async<'a list>, which will take a seq of Async types, prep them to run in parallel, and output a single Async.

I was wondering if there is a similar Async.Sequential which has the same type signature, but runs each item in sequence one after the other? I feel like I must be missing something obvious?

I'd like to do something like the following:

async {
    let! results =
        myItems
        |> List.map myAsynchronousOperation
        |> Async.Sequential

    ... do something with results
}
like image 203
Tub Avatar asked Feb 18 '26 01:02

Tub


2 Answers

I don't think there's one built in, but should be trivial to write your own:

let sequential s = async {
    let results = ResizeArray()
    for a in s do
        let! result = a
        results.Add(result)
    return List.ofSeq results
}
like image 59
kvb Avatar answered Feb 21 '26 15:02

kvb


Evaluating the items in a seq<Async<'a>> in-order and returning a list is effectively just a foldBack on the sequence where you want to evaluate the async before simply cons-ing it onto a list. While kvb's solution certainly works, you could also do it with a Seq.foldBack like so:

module Async =
    let sequential s = 
        Seq.foldBack (fun cur acc -> async.Bind(cur, fun head -> 
            async.Bind(acc, fun tail -> async.Return(head :: tail)))) s (async.Return [])
like image 23
Aaron M. Eshbach Avatar answered Feb 21 '26 13:02

Aaron M. Eshbach