I have this function:
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
}
I use it in an asyncResult block like this:
asyncResult {
let! x = Retry.retryAsync
Retry.shouldRetryExchange
Retry.defaultRetryIntervals
(fun r -> warn $"retry {r}/{Retry.defaultRetryIntervals.Length}")
(fun _ -> loadExchangeSettingsAsync rest)
...
return ...
}
but in some cases, I want to ignore the result; however:
asyncResult {
do! Retry.retryAsync
Retry.shouldRetryExchange
Retry.defaultRetryIntervals
(fun r -> warn $"retry {r}/{Retry.defaultRetryIntervals.Length}")
(fun _ -> loadExchangeSettingsAsync rest)
...
return ...
}
will give me:
[FS0001] This expression was expected to have type 'Result<unit,ExchangeError>' but here has type 'unit'
I don't understand why since the expression is returning the right type, it's the same one as above.
do!
only works on expressions that return Async<unit>
, so you'll have to pipe it to Async.Ignore
first:
do! Retry.retryAsync
Retry.shouldRetryExchange
Retry.defaultRetryIntervals
(fun r -> warn $"retry {r}/{Retry.defaultRetryIntervals.Length}")
(fun _ -> loadExchangeSettingsAsync rest)
|> Async.Ignore