首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >建筑平底灯笼

建筑平底灯笼
EN

Stack Overflow用户
提问于 2015-10-15 11:46:33
回答 1查看 66关注 0票数 2

我在F#中使用引号来构建一个函数,该函数检查单个输入是否满足许多情况中的任何一种。也就是说,函数的主体类似于... || ... || ...,其中||s的数量是在运行时确定的。稍微简化一下,我现在的情况是

代码语言:javascript
复制
let vals = [|1..3|]
let currentfilter =
    vals
    |> Array.fold (fun acc i ->
        <@ fun j -> (%acc) j || j = i @>)
        <@ fun _ -> false @>

生成树

代码语言:javascript
复制
val currentfilter : Expr<(int -> bool)> =
  Lambda (j,
        IfThenElse (Application (Lambda (j,
                                         IfThenElse (Application (Lambda (j,
                                                                          IfThenElse (Application (Lambda (_arg1,
                                                                                                           Value (false)),
                                                                                                   j),
                                                                                      Value (true),
                                                                                      Call (None,
                                                                                            op_Equality,
                                                                                            [j,
                                                                                             Value (1)]))),
                                                                  j),
                                                     Value (true),
                                                     Call (None, op_Equality,
                                                           [j, Value (2)]))), j),
                    Value (true), Call (None, op_Equality, [j, Value (3)])))

最优的情况是,我想要生成的更像是

代码语言:javascript
复制
  Lambda (j,
        IfThenElse (IfThenElse (Call (None, op_Equality, [j, Value (1)]),
                                Value (true),
                                Call (None, op_Equality, [j, Value (2)])),
                    Value (true), Call (None, op_Equality, [j, Value (3)])))

(这是<@ fun j -> j = 1 || j = 2 || j = 3 @>生成的)

有什么简单的方法可以使第一个表达式变得更像第二个表达式呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-15 11:58:19

您可以编写代码,这样它就不会返回带引号的函数,而是返回在给定输入时生成引号的函数:

代码语言:javascript
复制
let vals = [|1..3|]

let currentfilter =
    vals |> Array.fold (fun acc i ->
        fun j -> <@ %(acc j) || %j = i @>)
        (fun _ -> <@ false @>)

在折叠中:

  • 初始值是一个返回false表达式的函数。
  • 聚合将生成的表达式与将输入(指定为引号)与值i进行比较的表达式组合在一起。

现在,为了创建完整的引用函数,我们想编写如下内容:

代码语言:javascript
复制
<@ fun j -> %(currentfilter <@ j @>) @>

遗憾的是,这是行不通的--因为F#编译器在这里有点严格,并且不允许我们编写变量j可以脱离其作用域的代码(非常合理,但很不幸)。

因此,您可以通过手动构造引号来编写此代码:

代码语言:javascript
复制
open Microsoft.FSharp.Quotations

let v = Var.Global("j", typeof<int>)
Expr.Lambda(v, currentfilter (Expr.Cast(Expr.Var(v))))
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33147688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档