【问题标题】:can't compile code in computation expression, in F#无法在 F# 中编译计算表达式中的代码
【发布时间】:2021-08-12 19:07:39
【问题描述】:

我有这个功能:

let rec retryAsync<'a> (shouldRetry: 'a -> bool) (retryIntervals: TimeSpan list) (onRetryNotice: int -> unit) (request: unit -> Async<'a>) : Async<'a> =
    async {
        let! result = request()
        match shouldRetry result, retryIntervals with
        | true, head::rest ->
            onRetryNotice retryIntervals.Length
            Thread.Sleep(head)
            return! retryAsync shouldRetry rest onRetryNotice request
        | false, _
        | _, [] ->
            return result
    }

我在这样的 asyncResult 块中使用它:

asyncResult {
    let! x = Retry.retryAsync
                 Retry.shouldRetryExchange
                 Retry.defaultRetryIntervals
                 (fun r -> warn $"retry {r}/{Retry.defaultRetryIntervals.Length}")
                 (fun _ -> loadExchangeSettingsAsync rest)
    ...
    return ...
}

但在某些情况下,我想忽略结果;但是:

asyncResult {
    do!  Retry.retryAsync
             Retry.shouldRetryExchange
             Retry.defaultRetryIntervals
             (fun r -> warn $"retry {r}/{Retry.defaultRetryIntervals.Length}")
             (fun _ -> loadExchangeSettingsAsync rest)
    ...
    return ...
}

会给我:

[FS0001] 此表达式应具有类型 'Result' 但这里有类型 '单位'

我不明白为什么既然表达式返回了正确的类型,它就和上面的一样。

【问题讨论】:

  • 不确定asyncResult CE 是否支持do!。如果是这样,我猜表达式的返回类型需要是Async&lt;Result&lt;unit, unit&gt;&gt;。忽略结果的另一个选项是使用let! _ = expr

标签: f# computation-expression


【解决方案1】:

do! 仅适用于返回 Async&lt;unit&gt; 的表达式,因此您必须先将其通过管道传递给 Async.Ignore

do!  Retry.retryAsync
             Retry.shouldRetryExchange
             Retry.defaultRetryIntervals
             (fun r -> warn $"retry {r}/{Retry.defaultRetryIntervals.Length}")
             (fun _ -> loadExchangeSettingsAsync rest)
     |> Async.Ignore

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多