Шаблон соответствия F# для Expr‹int›

Я пытаюсь найти правильный шаблон для соответствия и запускаю 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, но здесь имеет тип 'a * 'b


person halcwb    schedule 06.06.2013    source источник


Ответы (1)


Нашел! По глупости я сначала попытался сопоставить шаблон массива, используя шаблон, разделенный запятыми (как разделитель списка в C#), который, очевидно, не работал в F#, жалуясь, что это не список, а кортеж и, следовательно, не Rex.

Чтобы сопоставить результат int или любой результат 'T:

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())

Работает как шарм.

person halcwb    schedule 17.06.2013
comment
Это была просто опечатка :) - person Luiz Felipe; 12.08.2015