F# - 从 Expr 中提取选项

发布于 2024-11-07 18:09:43 字数 300 浏览 0 评论 0原文

有没有办法从 Expr 中提取参数?

一个例子:

let hasStringOption (e:Expr<string option>) =
    let myOption : string option = ..some code to get the string option from e

如何获取 Expr 中的 string option 并将其分配给 myOption

Is there a way to extract a parameter from an Expr?

An example:

let hasStringOption (e:Expr<string option>) =
    let myOption : string option = ..some code to get the string option from e

How would I get the string option inside the Expr and assign it to myOption?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

明月夜 2024-11-14 18:09:43

在您的示例中,字符串选项 表示表达式返回类型,因此表达式本身可以任意复杂,并且需要某种评估策略,例如 @wmeyer 所示的 PowerPack。

但是,如果您实际上有一个字符串选项表达式,您可以使用标准库引用活动模式和反射来实现您自己的评估策略(此处显示的通用选项):

module P = Microsoft.FSharp.Quotations.Patterns

let extract (expr:Expr<'a option>) =
    match expr with
    | P.NewUnionCase (uci, args) ->
        if uci.Name = "Some" then
            match args.Head with
            | P.Value(value, ty) -> Some(value :?> 'a)
        else
            None:('a option)

let example1 = extract <@ None:int option @>
let example2 = extract <@ Some("hello world") @>

事实上,这种方法可能是您自己的策略的一部分,用于使用反射和活动模式递归地评估任意表达式,而不是 PowerPack 缓慢且有限的中间 LINQ 策略。

In your example, string option represents the expression return type, so the expression itself could be arbitrarily complex and requires some kind of evaluation strategy like the PowerPack's as @wmeyer has shown.

But if you actually have a string option expression you can use the standard library quotation active patterns and reflection to implement your own evaluation strategy (generic option shown here):

module P = Microsoft.FSharp.Quotations.Patterns

let extract (expr:Expr<'a option>) =
    match expr with
    | P.NewUnionCase (uci, args) ->
        if uci.Name = "Some" then
            match args.Head with
            | P.Value(value, ty) -> Some(value :?> 'a)
        else
            None:('a option)

let example1 = extract <@ None:int option @>
let example2 = extract <@ Some("hello world") @>

and indeed, such an approach may be a piece of your own strategy for recursively evaluating arbitrary expressions using reflection and active patterns rather than PowerPack's slow and limited intermediate LINQ strategy.

凤舞天涯 2024-11-14 18:09:43

引用 FSharp.PowerPack.Linq.dll 后,您可以执行以下操作:

  open Microsoft.FSharp.Quotations 
  open Microsoft.FSharp.Linq.QuotationEvaluation


  let hasStringOption (e:Expr<string option>) =
      let myOption : string option = e.Eval()
      myOption.IsSome

  printfn "%A" (hasStringOption <@ Some "hello" @>)
  printfn "%A" (hasStringOption <@ None @>)

但是,据报道,这非常慢,并且使用 LINQ 表达式作为中间步骤。

With FSharp.PowerPack.Linq.dll referenced you can do:

  open Microsoft.FSharp.Quotations 
  open Microsoft.FSharp.Linq.QuotationEvaluation


  let hasStringOption (e:Expr<string option>) =
      let myOption : string option = e.Eval()
      myOption.IsSome

  printfn "%A" (hasStringOption <@ Some "hello" @>)
  printfn "%A" (hasStringOption <@ None @>)

However, reportedly this is quite slow and uses LINQ expressions as an intermediary step.

时光匆匆的小流年 2024-11-14 18:09:43

遗憾的是(或没有),您无法评估 F# 引用。 F# PowerPack 将引用编译为 LINQ 表达式(可以进行求值)的能力有限。

Sadly (or not), you cannot evaluate F# quotations. The F# PowerPack has a limited ability to compile quotations to LINQ expressions (which can be evaluated).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文