有没有办法从Expr
?
一个例子:
let hasStringOption (e:Expr<string option>) =
let myOption : string option = ..some code to get the string option from e
我如何获得string option
中的Expr
并将其分配给myOption
?
答案 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表达式的能力有限(可以评估)。