Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous F中嵌套异步序列的展平#_Asynchronous_F#_Sequence - Fatal编程技术网

Asynchronous F中嵌套异步序列的展平#

Asynchronous F中嵌套异步序列的展平#,asynchronous,f#,sequence,Asynchronous,F#,Sequence,考虑一系列F#序列: let seqOf123 = seq { for i in 1..3 do yield i } let seqOf456 = seq { for i in 4..6 do yield i } let seqOf789 = seq { for i in 7..9 do yield i } let asyncSeqOf123 = async { return seqOf123 } let asyncSeqOf456 = async { return seqOf456 } le

考虑一系列F#序列:

let seqOf123 = seq { for i in 1..3 do yield i }
let seqOf456 = seq { for i in 4..6 do yield i }
let seqOf789 = seq { for i in 7..9 do yield i }
let asyncSeqOf123 = async { return seqOf123 }
let asyncSeqOf456 = async { return seqOf456 }
let asyncSeqOf789 = async { return seqOf789 }
。。。以及包含所有这些元素的序列:

let seqOfSeqOfNums = 
    seq {
        yield seqOf123
        yield seqOf456
        yield seqOf789
    }
现在我们有了一个序列,我们可以使用内置的Seq.concat函数和wrap in async子句将其展平以异步执行:

let firstAsyncSeqOfNums = async { return Seq.concat seqOfSeqOfNums }
我们得到了一个9个数字的异步序列,带有签名
async
,我们将回到这里

现在考虑一系列异步序列:

let seqOf123 = seq { for i in 1..3 do yield i }
let seqOf456 = seq { for i in 4..6 do yield i }
let seqOf789 = seq { for i in 7..9 do yield i }
let asyncSeqOf123 = async { return seqOf123 }
let asyncSeqOf456 = async { return seqOf456 }
let asyncSeqOf789 = async { return seqOf789 }
。。。以及包含它们的序列:

let seqOfAsyncSeqOfNums = 
    seq {
        yield asyncSeqOf123
        yield asyncSeqOf456
        yield asyncSeqOf789
    }
我们现在有一个类型为
seq
的序列。我们不能使用Seq.concat展平这个,因为它是一个异步序列序列。那么,我们如何将其转换为一种类型
Async
,其中所有整数数据都被展平?我们可以尝试执行以下操作:

let secondAsyncSeqOfNums = 
    async {
        return seqOfAsyncSeqOfNums
        |> Seq.map (fun x -> x |> Async.RunSynchronously)
        |> Seq.concat
    }

它似乎完成了它的工作:它有一个类型
Async
,如果我们将它管道化为Async.RunSynchronously,它将生成相同的9个整数序列。但它产生相同序列的方式并不等同于上面出现的firstAsyncSeqOfNums。secondAsyncSeqOfNums的实现在生成单个展平序列期间对每个嵌套的整数序列调用Async.runsynchronous。但这能避免吗?请注意,我们正在生成一个异步展平序列,理想情况下只需对async.RunSynchronously进行一次调用即可评估其内容。但是,如果不多次调用Async.RunSynchronously,我无法找到重写代码的方法。

您是否正在寻找类似这样的方法:

> let aMap f wf = async {                              
-    let! a = wf
-    return f a
-    };;

val aMap : f:('a -> 'b) -> wf:Async<'a> -> Async<'b>

> let aConcat wf = Async.Parallel wf |> aMap Seq.concat;;   

val aConcat : wf:seq<Async<#seq<'b>>> -> Async<seq<'b>>
>让aMap f wf=async{
-设!a=wf
-返回f a
-    };;
valamap:f:('a->'b)->wf:Async
>设aConcat wf=Async.Parallel wf |>aMap Seq.concat;;
val aConcat:wf:seq>

它的名称稍有不同,但我认为您需要的是(您可能希望将它与前面提到的其他一些函数一起使用-只需播放一点;))Async.Parallel将序列转换为数组以进行并行执行,但它不能用于展平嵌套异步序列的序列,可以吗?它基本上会让你
seq>
(因此它会把
异步的
拉出来)`-不,你可以继续你用
seq.concat所做的事情(或者我会这么做)
)-在我看来,这比同步运行一切要好,因为你失去了异步的所有优势)顺便说一句:很遗憾(有些奇怪)没有
Async.map
所以你不能把它们很好地结合在一起,你必须深入到
Async{…}
或者自己把
Async
变成一个函子你能用一个例子来说明吗?我确实使用了Async.Parallel,但无法让它按我的目的工作。关于Async.map,很容易编写一个,如我的另一个问题的答案所示:谢谢,它成功了!是的,Async.Parallel和Async.map(aMap)的组合成功了。很高兴我能提供帮助-FP中的好东西是:正确地获取类型,并且通常很好地使用;)是的,我花了一段时间努力摆脱对Async.RunSynchronously的多次调用。现在一切都很完美:-)