Functional programming 提取变量的名称

Functional programming 提取变量的名称,functional-programming,f#,Functional Programming,F#,我们如何在F#中构建一个输出传入变量名称的函数?例如: let someVar1 = "x" getVarname someVar1 //output would be "someVar1" let someVar2 = "y" getVarname someVar2 //output would be "someVar2" let f toString = fun a -> printfn "%s: %d" (toString a) a let x = 1 f getVarname

我们如何在F#中构建一个输出传入变量名称的函数?例如:

let someVar1 = "x"
getVarname someVar1 //output would be "someVar1"

let someVar2 = "y"
getVarname someVar2 //output would be "someVar2"

let f toString = fun a -> printfn "%s: %d" (toString a) a
let x = 1
f getVarname x      //output would be: "x: 1"

我在C#here()中发现了一个类似的问题,但我无法使它在F#中工作。

实现的
名称在F#core中有运算符,但F#5编译器位尚未发布。
当它出现时,您可以使用它来获取符号的名称

let someVar1 = None
let name = nameof someVar1 // name = "someVar1"
现在,我们可能会滥用dynamic运算符来获取垫片,您最终可以用
nameof

let name = ()
let (?) _ name = string name
用法:

let someVar1 = None
let name = name?someVar1
它读起来不太糟糕,而且你会有某种程度的自动完成

如果您真的希望能够在调用站点检索本地名称和值,可以使用引号

let printVar = function
|  ValueWithName(value, _type, name) -> printfn "%s = %A" name value 
| _ -> ()
不过使用起来有点吵

let someVar1 = 12
printVar <@ someVar1 @> //prints someVar1 = 12
让someVar1=12
printVar//打印someVar1=12

实现的
名称在F#core中有运算符,但F#5编译器位尚未发布。
当它出现时,您可以使用它来获取符号的名称

let someVar1 = None
let name = nameof someVar1 // name = "someVar1"
现在,我们可能会滥用dynamic运算符来获取垫片,您最终可以用
nameof

let name = ()
let (?) _ name = string name
用法:

let someVar1 = None
let name = name?someVar1
它读起来不太糟糕,而且你会有某种程度的自动完成

如果您真的希望能够在调用站点检索本地名称和值,可以使用引号

let printVar = function
|  ValueWithName(value, _type, name) -> printfn "%s = %A" name value 
| _ -> ()
不过使用起来有点吵

let someVar1 = 12
printVar <@ someVar1 @> //prints someVar1 = 12
让someVar1=12
printVar//打印someVar1=12

如果使用引号和静态方法,则可以使用
ReflectedDefinition
属性在F#4中捕获变量的名称。以下示例中的
Demo.GetVarName
静态方法返回用作参数的变量名称和值:

open Microsoft.FSharp.Quotations

type Demo = 
  static member GetVarName([<ReflectedDefinition(true)>] x:Expr<int>) = 
    match x with
    | Patterns.WithValue(_, _, Patterns.ValueWithName(value, _, name)) ->
        name, value :?> int
    | _ -> failwithf "Argument was not a variable: %A" x

let test ()= 
  let yadda = 123
  Demo.GetVarName(yadda)

test()

如果使用引号和静态方法,则可以使用
ReflectedDefinition
属性捕获F#4中变量的名称。以下示例中的
Demo.GetVarName
静态方法返回用作参数的变量名称和值:

open Microsoft.FSharp.Quotations

type Demo = 
  static member GetVarName([<ReflectedDefinition(true)>] x:Expr<int>) = 
    match x with
    | Patterns.WithValue(_, _, Patterns.ValueWithName(value, _, name)) ->
        name, value :?> int
    | _ -> failwithf "Argument was not a variable: %A" x

let test ()= 
  let yadda = 123
  Demo.GetVarName(yadda)

test()


你试过F#5的名字吗?我听说过这个函数,但我不知道如何在脚本中使用它。尽管我已经打开了Microsoft.FSharp.Core.Operators,但它一直显示错误(“未定义值或构造函数'nameof')。我正在使用Visual Studio Community 2019 16.5.3。您尝试过F#5的名称吗?我听说过这个函数,但我不知道如何在脚本中使用它。尽管我已经打开了Microsoft.FSharp.Core.Operators,但它一直显示错误(“未定义值或构造函数'nameof')。我正在使用Visual Studio Community 2019 16.5.3。非常感谢,Asti!但是假设我们有一个函数f getName=(fun a->printfn“%s:%d”(getName a)a),用户将其调用为f getName x(其中x是在某处定义的变量,等于1)。我希望得到“x:1”作为输出,而不是“a:1”。在这种情况下,我如何使用您的解决方案?使用
nameof
也不可能
nameof
将绑定到本地符号。谢谢!我编辑了我的问题并添加了上面提供的示例。我添加了一个替代解决方案。非常感谢,Asti!但是假设我们有一个函数f getName=(fun a->printfn“%s:%d”(getName a)a),用户将其调用为f getName x(其中x是在某处定义的变量,等于1)。我希望得到“x:1”作为输出,而不是“a:1”。在这种情况下,我如何使用您的解决方案?使用
nameof
也不可能
nameof
将绑定到本地符号。谢谢!我编辑了我的问题并添加了我上面提供的示例。我添加了一个替代解决方案。嗨,托马斯。谢谢你的解释!我使用下面的函数尝试了您的完整解决方案(包括PropertyGet):let f=fun a->sprintf“%s:%d”(a |>Demo.GetVarName |>fst)a;设x=1;f x。输出是“arg00:1”。问题是
|>
操作符是内联的,因此编译器可能会看到类似
(fun arg00->Demo.GetVarName(arg00))的东西。这只适用于直接调用,即
Demo.GetVarName(a)
。在进行了您建议的更正后,现在我得到了“a:1”作为输出,而不是“x:1”。是否可以获取“x:1”@FRocha否,这不适用于封装在函数中的代码-它提供直接作为参数传递给
Demo.GetVarName
的变量的名称。换句话说,如果你想定义一个方法,比如说
Chart.Plot(无论什么)
来获取参数的变量名,你需要按照我的答案中所示的方式来定义它。嗨,Tomas。谢谢你的解释!我使用下面的函数尝试了您的完整解决方案(包括PropertyGet):let f=fun a->sprintf“%s:%d”(a |>Demo.GetVarName |>fst)a;设x=1;f x。输出是“arg00:1”。问题是
|>
操作符是内联的,因此编译器可能会看到类似
(fun arg00->Demo.GetVarName(arg00))的东西。这只适用于直接调用,即
Demo.GetVarName(a)
。在进行了您建议的更正后,现在我得到了“a:1”作为输出,而不是“x:1”。是否可以获取“x:1”@FRocha否,这不适用于封装在函数中的代码-它提供直接作为参数传递给
Demo.GetVarName
的变量的名称。换句话说,如果你想定义一个方法,比如说
Chart.Plot(无论什么)
来获取参数的变量名,你需要按照我的答案中所示的方式来定义它。