F# - 从Expr中提取选项

时间:2011-05-16 19:02:36

标签: f#

有没有办法从Expr

中提取参数

一个例子:

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

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

3 个答案:

答案 0 :(得分:4)

在您的示例中,string option表示表达式返回类型,因此表达式本身可能是任意复杂的,需要某种评估策略,如@wmeyer所示的PowerPack。< / p>

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

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策略。

答案 1 :(得分:3)

引用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表达式作为中间步骤。

答案 2 :(得分:0)

可悲(或不),您无法评估F#报价。 F#PowerPack编译引用LINQ表达式的能力有限(可以评估)。