Cannot get the name of a function passed as a parameter with code quotations, in F#

85 Views Asked by At

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?

1

There are 1 best solutions below

4
Tomas Petricek On BEST ANSWER

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.

Related Questions in F#