0

Let's have the following function definition:

module Helpers =

    [<ReflectedDefinition>]
    let dummy (x:int) = x.ToString()

By using the following quotation we get its representation as a lambda expression:

<@ dummy @>;;

val it : Expr<(int -> string)> =
Lambda (x, Call (None, dummy, [x]))

In this previous question it is stated that quotations represent code quoted syntactically, that meaning that we can not get the same expression by wrapping the same function within other function:

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

val it : Expr<(int -> string)> =
Value (<fun:it@6-3>)

Is it possible to build the former expression (Lambda (x, Call (None, dummy, [x]))) programmatically?. The objective would be to implement a dynamic qwrap for simple functions ('a -> 'b). The resulting expression is going to be analyzed and I'm interested in being able to keep the function and args names as they are written in the original function.

4

1 回答 1

2

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

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

如果你想创建一个包含另一个引用的引用,你的论点f也需要是一个引用。然后您可以使用<@ %f @>创建一个包含原始引号的新引号(%语法是拼接运算符)。

这是一个添加零检查的简单示例:

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

您可以qwrap使用任何带引号的函数作为参数调用:

let dummy (x:int) = x.ToString()
qwrap <@ dummy @>
于 2014-09-11T13:13:32.957 回答