代码之家  ›  专栏  ›  技术社区  ›  Thomas

无法获取作为带有代码引号的参数传递的函数的名称,在F中#

  •  0
  • Thomas  · 技术社区  · 3 年前

    我有一个函数,看起来是这样的:

    let rec retryAsync (retryAttempts: TimeSpan list) (request: unit -> Async<Result<'a, ExchangeError>>) : Async<Result<'a, ExchangeError>> = ....
    

    并且,在出现错误时,我想将传递的函数的名称打印为' 要求 '. 其签名如下:

    unit -> Async<Result<'a, ExchangeError>>
    

    我想过使用这样的东西(我在网上找到的代码的略微修改版本):

    module DocumentGetter =
        let GetName ([<ReflectedDefinition>]x:Expr<_->_>) =
            match x with
            | DerivedPatterns.Lambdas(_, Patterns.Call(_,methodInfo,_)) ->
                methodInfo.Name
            | _ -> "unknown"
    

    但后来我得到了这个编译错误:

    [FS001]类型‘单元->异步<结果<'a、 Exchange错误>>'与类型“Quotations”不兼容。Expr<('b->'c)>'

    如果我传递主函数(retrysync),我可以获取名称,但无法获取传递给它的函数的名称。为什么?

    0 回复  |  直到 3 年前
        1
  •  1
  •   Tomas Petricek    3 年前

    基于的F#引号的隐式转换 ReflectedDefinition 属性不适用于let绑定函数,而仅适用于静态成员。以下工作符合预期:

    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
    

    也就是说,我不太确定你的情况是什么。听起来你正试图做一些非常复杂的事情——我认为可能有一种更容易的方法来解决你的实际问题,而不需要这样做。

    推荐文章