I have a function that looks like that:
let rec retryAsync (retryAttempts: TimeSpan list) (request: unit -> Async<Result<'a, ExchangeError>>) : Async<Result<'a, ExchangeError>> = ....
and, upon an error I would like to print the name of the function passed as 'request'. It has this signature:
unit -> Async<Result<'a, ExchangeError>>
I thought about using something like this (slightly modified version of code I found online):
module DocumentGetter =
let GetName ([<ReflectedDefinition>]x:Expr<_->_>) =
match x with
| DerivedPatterns.Lambdas(_, Patterns.Call(_,methodInfo,_)) ->
methodInfo.Name
| _ -> "unknown"
but then I get this compile error:
[FS0001] The type 'unit -> Async<Result<'a,ExchangeError>>' is not compatible with the type 'Quotations.Expr<('b -> 'c)>'
If I pass the main function (retryAsync), I can get the name out, but I can't get the name of the function passed to it. Why is that?
Implicit conversion to F# quotations based on the ReflectedDefinition
attribute does not work for let-bound functions, but only for static members. The following works as expected:
type DocumentGetter =
static member GetName ([<ReflectedDefinition>]x:Expr<_->_>) =
match x with
| DerivedPatterns.Lambdas(_, Patterns.Call(_,methodInfo,_)) ->
methodInfo.Name
| _ -> "unknown"
let rec retryAsync (retryAttempts: TimeSpan list)
(request: unit -> Async<Result<'a, ExchangeError>>)
: Async<Result<'a, ExchangeError>> = failwith "!"
DocumentGetter.GetName retryAsync
That said, I'm not quite sure what your scenario for this is. It sounds like you are trying to do something pretty complicated - I think there might be an easier way to solve your actual problem without doing this.