如何在F#中实现递归async函数?同步改异步报FS0588错误
错误根因
你遇到的FS0588错误是因为async计算表达式要求块内最后一个元素必须是返回值(用return/return!声明),你包裹async块后,内部递归函数的写法没有适配异步规则,同时递归调用异步函数时没有用return!触发执行。
具体修改要点
- 内部递归函数
get本身要返回异步类型,逻辑包裹在async块内 - 调用异步方法
GetCandlesAsync时用let!等待结果 - 递归调用
get时用return!执行异步递归逻辑 - 最终返回结果分支用
return把数组包装进异步上下文 - 外层初始调用
get时用return!触发整个异步流程
完整可运行代码
let getCandlesFrom (exchange: IExchange) (instrument: Instrument) (interval: TimeSpan) (fromTime: DateTime) = async { let rec get (c: CandleData array) (f: DateTime) = async { let now = DateTime.UtcNow //info $"requesting {f} - {now}" let! candles = exchange.GetCandlesAsync(instrument, interval, f, now) if candles.IsError then failwith candles.GetError.Describe else //info $"received data {candles.Get.[0].Timestamp} - {candles.Get.[^0].Timestamp}" let c = Array.append c candles.Get if c.[^0].Timestamp < now - interval then return! get c (c.[^0].Timestamp + interval) else return c } return! get [||] fromTime }
补充说明
修改后的函数返回类型为Async<CandleData array>,调用时可以用Async.RunSynchronously同步等待结果,也可以嵌入其他异步流程中用let!等待结果。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

