2016-11-24 74 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