try/with 在 asyncResult 块中,在 F# 中?

try/with in an asyncResult block, in F#?

try/finally 在 asyncResult 块中的工作情况如何:

let loadAndParseTrades ticker (dayDate: DateTime) : Async<Result<TradeData list, ExchangeError>> =
    asyncResult {
        try
            // wait for loading semaphore
            loadingSemaphores.WaitOne() |> ignore
        
            // load the data
            let date  = dayDate.Floor (TimeSpan.FromDays(1))
            let func  = client.GetAsync(buildTradesRequest ticker date) |> Async.AwaitTask
            let! data = getDataAsync func

            // parse it and return it                
            return Parser.parseTrades ticker data []
        
        finally
            loadingSemaphores.Release() |> ignore
    }

我有这个函数加载一个大的 zip 文件并解析它。

我想在这里捕获异常并且return一个错误:

try
    try
        // wait for loading semaphore
        loadingSemaphores.WaitOne() |> ignore
    
        // load the data
        let date  = dayDate.Floor (TimeSpan.FromDays(1))
        let func  = client.GetAsync(buildTradesRequest ticker date) |> Async.AwaitTask
        let! data = getDataAsync func

        // parse it and return it                
        return Parser.parseTrades ticker data []

    with ex ->
        let err = Error (ExchangeError.ServiceException ex)  // <- Result<'a,ExchangeError>
        AsyncResult.returnError err             
    
finally
    loadingSemaphores.Release() |> ignore

但是这里似乎不可能:

  Loader.fs(75, 21): [FS0193] Type constraint mismatch. The type 
    'Async<Result<unit,'a>>'    
is not compatible with type
    'Async<Result<TradeData list,ExchangeError>>'

我在这里错过了什么?


编辑:

添加了一个大家可以编译的示例

let testSomethingAsync x =
    async {
        if x % 2 = 0 then
            return Ok x
        else
            return Error "oh, no!"
    }        

let doSomethingAsync x =
    asyncResult {
        try    
            let! a = testSomethingAsync x
            return a * 2
        with ex ->

            // none of these compile
            // AsyncResult.returnError "no no no"            
            // Error (AsyncResult.returnError "no no no")             
            // return (AsyncResult.returnError "no no no")
            // return (Error (AsyncResult.returnError "no no no"))             
               

自从:

let returnError x = Error x |> Async.singleton

我们可以假设行:

Error (AsyncResult.returnError "no no no")             
return (Error (AsyncResult.returnError "no no no" 

肯定不会编译。

行:

AsyncResult.returnError "no no no"           

将无法编译:

Type constraint mismatch. The type 'Async<Result<unit,'a>>' is not compatible with type 'Async<Result<int,string>>' 

还有一行:

return (AsyncResult.returnError "no no no")

将无法编译:

This expression was expected to have type 'int' but here has type 'Async<Result<'a,'b>>'

我有点迷路了...

以下应该有效:

let doSomethingAsync x =
    asyncResult {
        try    
            let! a = testSomethingAsync x
            return a * 2
        with ex ->
            return! AsyncResult.error "no no no"
    }