简体   繁体   English

如何在 F# 中创建递归异步 function?

[英]how can I make a recursive async function in F#?

I have the following:我有以下内容:

let getCandlesFrom (exchange: IExchange) (instrument: Instrument) (interval: TimeSpan) (fromTime: DateTime) =
    let rec get (c: CandleData array) (f: DateTime) =
        let now = DateTime.UtcNow
        //info $"requesting {f} - {now}"
        let candles = exchange.GetCandles(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
                get c (c.[^0].Timestamp + interval)
            else
                c

    get [||] fromTime

I would like to move the line:我想移动这条线:

let candles = exchange.GetCandles(instrument, interval, f, now)

to an async call:到异步调用:

let! candles = exchange.GetCandlesAsync(instrument, interval, f, now)

but if I wrap the whole function in an async block, the recursive function doesn't compile and I get this error:但是如果我将整个 function 包装在一个异步块中,则递归 function 不会编译,我会收到此错误:

DataSource.fs(14, 13): [FS0588] The block following this 'let' is unfinished. DataSource.fs(14, 13): [FS0588] 这个 'let' 后面的块未完成。 Every code block is an expression and must have a result.每个代码块都是一个表达式,并且必须有一个结果。 'let' cannot be the final code element in a block. 'let' 不能是块中的最后一个代码元素。 Consider giving this block an explicit result.考虑给这个块一个明确的结果。

I don't see your code producing the error but you must have forgotten something (after the let ) - this should work:我没有看到您的代码产生错误,但您一定忘记了一些东西(在let之后) - 这应该有效:

let getCandlesFrom (exchange: IExchange) (instrument: Instrument) (interval: TimeSpan) (fromTime: DateTime) =
    let rec get (c: CandleData array) (f: DateTime) =
        asnyc {
            let now = DateTime.UtcNow
            //info $"requesting {f} - {now}"
            let! candles = exchange.GetCandlesAsync(instrument, interval, f, now)
            if candles.IsError then
                return (failwith candles.GetError.Describe)
            else
                let c = Array.append c candles.Get
                if c.[^0].Timestamp < now - interval then
                    return! get c (c.[^0].Timestamp + interval)
                else
                    return c
    }
    get [||] fromTime

notice the return and the return!注意returnreturn! for the recursive call - you need those there对于递归调用 - 你需要那些

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM