【问题标题】:Pattern match list cons quotation模式匹配列表 cons 引用
【发布时间】:2016-11-24 01:41:00
【问题描述】:

我正在尝试编写一个通用的条件评估器,类似于 Lisp/Scheme 人们所说的 cond,使用引号,因为它们是获得按名称调用语义的最简单方法。我在与 list cons 操作进行模式匹配时遇到了问题,并且似乎无法确切地找出如何表示它。到目前为止,这是我所拥有的:

open FSharp.Quotations.Evaluator
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns

let rec cond = function
  | NewUnionCase (Cons, [NewTuple [condition; value]; tail]) ->
    if QuotationEvaluator.Evaluate <| Expr.Cast(condition)
      then QuotationEvaluator.Evaluate <| Expr.Cast(value)
      else cond tail

  | _ -> raise <| MatchFailureException ("cond", 0, 0

问题在于模式匹配的第一个分支中的 Cons 标识符 - 它不存在,我不知道如何表示列表 :: 数据构造函数。

对 list cons 数据构造函数进行模式匹配的正确方法是什么?

【问题讨论】:

  • 为什么要引用?为什么不运行?
  • 仔细想想,为什么要实施这样的事情呢? if - then - elif - else 怎么了?
  • @FyodorSoikin,引号 (&lt;@ ... @&gt;) 的输入速度比函数 (fun () -&gt; ...) 更快,并且可以更轻松地进行解构和操作。至于总体理由,我试图证明我们不需要 github.com/fsharp/fslang-suggestions/issues/519 的新语法

标签: f#


【解决方案1】:

我认为没有什么简单的方法可以直接在模式中写Cons,但是您可以使用when 子句来检查联合案例是否是"Cons" 类型的list&lt;T&gt; 类型的案例:

let rec cond = function
  | NewUnionCase (c, [NewTuple [condition; value]; tail]) 
      when c.Name = "Cons" && c.DeclaringType.IsGenericType &&
        c.DeclaringType.GetGenericTypeDefinition() = typedefof<_ list> -> 
      Some(condition, value, tail)
  | _ -> 
      None

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    相关资源
    最近更新 更多