2016-11-24 53 views
1

我正在尝试使用引号来编写一个通用条件评估程序,类似于Lisp/Scheme人员调用cond,因为它们是获取按名称语义的最简单方法。我对列表缺陷操作遇到了模式匹配问题,并且似乎无法准确找出如何表示它。这是我到目前为止有:模式匹配列表使用引用

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标识符 - 它不存在,我无法弄清楚如何表示列表::数据构造函数。

模式匹配列表缺点数据构造函数的正确方法是什么?

+1

为什么要报价?为什么不起作用? –

+1

想想吧,为什么要实施这样的事情呢? 'if - then - elif - else'有什么问题? –

+1

@FyodorSoikin,引用('<@ ... @>')比函数('fun() - > ...')更快地输入,并且可以更容易地解构和操纵。至于总的理由,我试图证明我们不需要新的语法https://github.com/fsharp/fslang-suggestions/issues/519 – Yawar

回答

2

我不认为这是在直接图案写入Cons的任何简单的方法,但可以使用when子句检查工会的情况下,是否是一个名为list<T>"Cons"情况:

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 
+0

适合我,谢谢! – Yawar