在F#中,“let! ... and! ...”结构只能在什么情况下使用?

3

我有如下的代码:

async {
    ...
    let! s0 = ZonesDatabase.upsertConsolidationZonesAsync       credentials exchangeName instrument interval zones
    and! s1 = FairPricesDatabase.upsertFairPricesAsync          credentials exchangeName instrument interval fairPrices
    and! s2 = LiquidityLinesDatabase.upsertLiquidityLinesAsync  credentials exchangeName instrument interval liquidityLines
    and! s3 = EventsDatabase.insertEventsAsync                  credentials exchangeName instrument interval events

这是针对数据库中4个不同表格的写入事件。如果其中一个写入失败,其他操作仍然可以成功完成。
但在尝试编译时,出现以下错误:
[FS3343] 'let! ... and! ...'结构只能用于计算表达式生成器定义了'Bind4'方法或适当的'MergeSource'和'Bind'方法的情况。
这是否意味着在添加'and!'之后未更新异步生成器?

正确,异步不支持 and! - Phillip Carter
1个回答

0

FSharp.Core中还没有实现BindNMergeSources方法,因此您必须自己实现它。对于顺序执行,实现可能类似于以下内容:

type AsyncBuilder with
    member _.Bind2(a1: Async<'T>, a2: Async<'U>, f) = async {
        let! r1 = async {
            match! a1 |> Async.Catch with
            | Choice1Of2 ok -> return Ok ok
            | Choice2Of2 err -> return Error err
        }
        let! r2 = async {
            match! a2 |> Async.Catch with
            | Choice1Of2 ok -> return Ok ok
            | Choice2Of2 err -> return Error err
        }
        return! f (r1, r2)
    }
    
    member self.Bind3(a1: Async<'T>, a2: Async<'U>, a3: Async<'W>, f) = self.Bind2(a1, a2, fun (r1, r2) -> async {
        let! r3 = async {
            match! a3 |> Async.Catch with
            | Choice1Of2 ok -> return Ok ok
            | Choice2Of2 err -> return Error err
        }
        return! f (r1, r2, r3)
    }) 

此外,您可能想查看F# GitHub存储库中这些方法的默认实现的讨论。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接