Is there any primitive in the langage to compose async1 then async2, akin to what parallel does for parallel execution planning ?
to further clarify, I have 2 async computations
let toto1 = Async.Sleep(1000)
let toto2 = Async.Sleep(1000)
I would like to create a new async computation made of the sequential composition of toto1 and toto2
let toto = Async.Sequential [|toto1; toto2|]
upon start, toto would run toto1 then toto2, and would end after 2000 time units
The async.Bind
operation is the basic primitive that asynchronous workflows provide for sequential composition - in the async
block syntax, that corresponds to let!
. You can use that to express sequential composition of two computations (as demonstrated by Daniel).
However, if you have an operation <|>
that Daniel defined, than that's not expressive enough to implement async.Bind
, because when you compose things sequentially using async.Bind
, the second computation may depend on the result of the first one. The <e2>
may use v1
:
async.Bind(<e1>, fun v1 -> <e2>)
If you were writing <e1> <|> <e2>
then the two operations have to be independent. This is a reason why the libraries are based on Bind
- because it is more expressive form of sequential composition than the one you would get if you were following the structure of Async.Parallel
.
If you want something that behaves like Async.Parallel
and takes an array, then the easiest option is to implement that imperatively using let!
in a loop (but you could use recursion and lists too):
let Sequential (ops:Async<'T>[]) = async {
let res = Array.zeroCreate ops.Length
for i in 0 .. ops.Length - 1 do
let! value = ops.[i]
res.[i] <- value
return res }