Seq.reduce
принимает функцию и последовательность и сокращает список, используя функцию. То есть результат сокращения последовательности {a1;a2;a3;...;an}
с помощью функции f
будет f(f(...f(f(a1,a2),a3),...),an))...)
. Однако передаваемая вами функция не может быть применена таким образом, поскольку тип возвращаемого значения (Async<float list * float>
) не соответствует типам аргумента (float list * float
). Что именно вы пытаетесь достичь?
Также имейте в виду, что вычисления async
отлично подходят для асинхронной работы, но не идеальны для параллельной работы. См. F #: Асинхронизация, Задачи и PLINQ, о, боже! и Параллельная библиотека задач и асинхронные рабочие процессы .
EDIT
Вот один из способов написать функцию, которая будет уменьшать количество элементов больше, чем вы ожидаете, работая примерно так:
[|a1; a2; a3; a4|]
[|f a1 a2; f a3 a4|]
f (f a1 a2) (f a3 a4)
На каждом этапе все применения f будут выполняться параллельно. При этом используется Async.Parallel
, что, как упоминалось выше, вероятно, менее целесообразно, чем использование библиотеки параллельных заданий (и даже может быть медленнее, чем обычная синхронная Array.reduce
). Таким образом, просто подумайте, что это демонстрационный код, показывающий, как собрать вместе асинхронные функции.
let rec reduce f (arr:_[]) =
match arr.Length with
| 0 -> failwith "Can't reduce an empty array"
| 1 -> arr.[0]
| n ->
// Create an array with n/2 tasks, each of which combines neighboring entries using f
Array.init ((n+1)/2)
(fun i ->
async {
// if n is odd, leave last item alone
if n = 2*i + 1 then
return arr.[2*i]
else
return f arr.[2*i] arr.[2*i+1]})
|> Async.Parallel |> Async.RunSynchronously
|> reduce f
Обратите внимание, что преобразование элементов в значения Async
и обратно все происходит внутри этой функции, поэтому она имеет тот же тип, что и Array.reduce
, и будет использоваться с обычной функцией compareVariance
, а не с aCompareVariance
.