本文介绍了F#中的异步函数链接(&;Quot;Chaining&;Quot;)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在F#中创建了一个函数来从Yahoo恢复历史数据(F#的经典异步示例):
let getCSV ticker dStart dEnd =
async {
let query = getFileUrl ticker dStart dEnd
let req = WebRequest.Create(query)
use! resp = req.AsyncGetResponse()
use stream= resp.GetResponseStream()
use reader = new StreamReader(stream)
let content = reader.ReadToEnd()
let ts = parseData content
return ts
}
现在,我可以通过执行以下操作异步运行此函数:
let test=
["MSFT";"YHOO"]
|>List.map (fun x -> getCSV x (DateTime.Parse("01.01.2000")) (DateTime.Parse("01.01.2010")))
|> Async.Parallel
|> Async.RunSynchronously
好的,很酷。
现在,我想知道的是如何对这个价格历史应用一些函数:
例如:
let getReturns (prices:(DateTime *float)list) =
[for i in 1..(prices.Length-1) -> i]
|> List.map (fun i ->(fst (List.nth prices i), (snd (List.nth prices i))/(snd (List.nth prices (i-1) )) - 1.0))
所以最简单的做法是:
let test2=
["MSFT";"YHOO"]
|>List.map (fun x -> getCSV x (DateTime.Parse("01.01.2000")) (DateTime.Parse("01.01.2010")))
|> Async.Parallel
|> Async.RunSynchronously
|> Array.map getReturns;;
但是,getReturns
函数在下载并分析每个文件后执行。
我想知道的是,是否可以在下载仍在进行的同时开始执行第二个函数:一旦MSFT完成,无需等到YHOO完成后才计算其回报.
我知道我可以修改getCSV
,但我想知道是否有办法在不更改以前编写的模块的情况下"链接"getReturn
函数.
推荐答案
我通常会直接在异步工作流中编写对函数的调用。这主要是风格或偏好的问题-我认为使用异步工作流编写的代码通常更明确,不会经常使用高阶函数(尽管它们有时仍然有用):
let test=
[ for stock in ["MSFT";"YHOO"] ->
async { let! data = getCSV stock (DateTime(2000, 1, 1)) (DateTime(2010, 1, 1))
return getReturns data } ]
|> Async.Parallel
|> Async.RunSynchronously
这意味着并行执行的工作流首先获取数据,然后调用getRteurns
提取数据。然后,整个操作被并行化。
getReturns
函数,使其采用异步工作流并返回异步工作流),或者定义一个函数Async.map
,该函数采用异步工作流并构造一个新的函数来对结果应用某些函数。
使用原始getReturns
函数,然后可以编写:
let test=
["MSFT";"YHOO"]
// For every stock name, generate an asynchronous workflow
|> List.map (fun x -> getCSV x (DateTime(2000, 1, 1)) (DateTime(2010, 1, 1)))
// For every workflow, transform it into a workflow that
// applies 'getReturns' to the result of the original workflow
|> List.map (Async.map getReturns)
// Run them all in parallel
|> Async.Parallel
|> Async.RunSynchronously
Async.map
的定义非常简单:
module Async =
let map f workflow = async {
let! res = workflow
return f res }
这篇关于F#中的异步函数链接(&;Quot;Chaining&;Quot;)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!