F# 在F中以编程方式构建lambda表达式#

F# 在F中以编程方式构建lambda表达式#,f#,quotations,F#,Quotations,让我们进行以下函数定义: module Helpers = [<ReflectedDefinition>] let dummy (x:int) = x.ToString() 模块帮助程序= [] 设dummy(x:int)=x.ToString() 通过使用以下引号,我们得到了其lambda表达式的表示形式: <@ dummy @>;; val it : Expr<(int -> string)> = Lambda (x, Cal

让我们进行以下函数定义:

module Helpers =

    [<ReflectedDefinition>]
    let dummy (x:int) = x.ToString()
模块帮助程序=
[]
设dummy(x:int)=x.ToString()
通过使用以下引号,我们得到了其lambda表达式的表示形式:

<@ dummy @>;;

val it : Expr<(int -> string)> =
Lambda (x, Call (None, dummy, [x]))
;;
val it:Expr字符串)>=
Lambda(x,调用(无,伪,[x]))
其中指出,引号表示按语法引用的代码,这意味着我们不能通过将相同的函数包装到其他函数中来获得相同的表达式:

let qwrap f = <@ f @>
qwrap dummy;;

val it : Expr<(int -> string)> =
Value (<fun:it@6-3>)
让qwrap f=
虚拟包装;;
val it:Expr字符串)>=
值()

是否可以通过编程方式构建前一个表达式(Lambda(x,Call(None,dummy,[x]))?。目标是为简单函数(“a->”b)实现动态qwrap。将对结果表达式进行分析,我希望能够保持函数和参数名称与原始函数中的名称相同。

为了确保我正确理解您的问题,您希望编写一些函数来包装函数(可能用引号表示)并在其周围添加一些其他内容

您的
qwrap
函数返回
Value
的原因是
只是创建一个引号,表示
f
的值,并将其作为对象嵌入-它不知道
f
是什么

如果要创建一个包含另一个引号的引号,则参数
f
也需要是引号。然后,您可以使用
创建包含原始引号的新引号(
%
语法是一个拼接运算符)

下面是一个简单的示例,其中添加了零检查:

let qwrap f = 
  <@ fun x -> 
      if x = 0 then failwith "No!" 
      else (%f) x @>

不,我想写一些函数,它接受一个函数“dummy”,它不是用引号表示的(任何函数'a->'b其中'a',b可以是任何类型),并且得到与手动引用相同的表示,即。我想知道,通过编程而不是引用,我们是否可以避免您在相关问题中提到的语法问题。因此,对于qwrap-dummy,我想让val-it:Expr-string)>=Lambda(x,Call(None,dummy,[x]),我想他想创建类似于
let-qwrap(f:'a->'b)=let x=Var(“x”,typeofOh,我明白了。从函数值中获取方法信息实际上是不可能的(嗯,这是不可能的)。我建议更改设计,这样就不需要了……我可能会尝试更改设计,但到目前为止,我已经获得了所有需要的功能(除了使所有功能都更加健壮的约定验证)。也许我可以尝试另一种方法,动态编写一些部分并使用Compiler.Services编译它们。没有太多的文档或示例。。。
let dummy (x:int) = x.ToString()
qwrap <@ dummy @>