Expr <int> </int>的F#匹配模式

时间:2013-06-06 11:29:41

标签: f# pattern-matching f#-3.0 quotations

我尝试找到匹配的正确模式并使用以下代码运行Expr<int>

open System.Linq

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

let runSelectQuery (q:Expr<IQueryable<'T>>) = 
    match q with
    | Application(Lambda(builder, Call(Some builder2, miRun, [Quote body])), queryObj) ->
        query.Run(Expr.Cast<Microsoft.FSharp.Linq.QuerySource<'T, IQueryable>>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

let runCountQuery (q:Expr<int>) = 
    match q with
    | Application(Lambda(builder, Call(None, miRun, [builder2, Quote body])), queryObj) ->
        query.Run(Expr.Cast<int>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

let countQuery source filter =
    let filter = match filter with | Some filter -> filter | _ -> <@ fun _ -> true @>
    <@ query { for item in source do
               where ((%filter) item)
               count } @>

runSelectQuery正确匹配Expr<IQueryable<'T>>模式。但是,我找不到与我的通用计数查询Expr<int>

匹配的正确模式

我从countQuery的签名派生的代码中的模式给了我一个:

  

预计此表达式具有类型       Expr但这里有类型       &#39; a *&#39; b

1 个答案:

答案 0 :(得分:3)

发现它!愚蠢的是我首先尝试使用逗号分隔模式匹配数组模式(就像C#中的列表分隔符一样),这显然在F#中不起作用,抱怨它不是列表而是tupple而不是Rex。

再次匹配int结果或任何'T result:

let runQueryToQueryable (q:Expr<IQueryable<'T>>) = 
    match q with
    | Application(Lambda(builder, Call(Some builder2, miRun, [Quote body])), queryObj) ->
        query.Run(Expr.Cast<Microsoft.FSharp.Linq.QuerySource<'T, IQueryable>>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

let runQueryToType (q:Expr<'T>) = 
    match q with
    | Application(Lambda(builder, Call(None, miRun, [builder2; Quote body])), queryObj) ->
           query.Run(Expr.Cast<'T>(body))
    | _ -> failwith "Cannot run this query %s" (q.ToString())

像魅力一样。