'try/with in an asyncResult block, in F#?
How is the try / finally working in an asyncResult block:
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
}
I have this function loading a large zip file and parsing it.
I would like to catch exceptions here and return an Error:
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
but then this doesn't seem to be possible here:
Loader.fs(75, 21): [FS0193] Type constraint mismatch. The type
'Async<Result<unit,'a>>'
is not compatible with type
'Async<Result<TradeData list,ExchangeError>>'
what am I missing here?
Edit:
Added a sample that everyone can compile
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"))
since:
let returnError x = Error x |> Async.singleton
we can assume that the lines:
Error (AsyncResult.returnError "no no no")
return (Error (AsyncResult.returnError "no no no"
will not compile for sure.
The line:
AsyncResult.returnError "no no no"
will fail to compile with:
Type constraint mismatch. The type 'Async<Result<unit,'a>>' is not compatible with type 'Async<Result<int,string>>'
And the line:
return (AsyncResult.returnError "no no no")
will fail to compile with:
This expression was expected to have type 'int' but here has type 'Async<Result<'a,'b>>'
I'm a bit lost here...
Solution 1:[1]
The following should work:
let doSomethingAsync x =
asyncResult {
try
let! a = testSomethingAsync x
return a * 2
with ex ->
return! AsyncResult.error "no no no"
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Tom Moers |