2015-07-06 5 views
2

У меня есть набор (под) выражений цитаты, которые все созданы на предыдущем этапе в программе. Теперь я хочу иметь возможность управлять созданием одного крупного выражения котировки, которое представляет собой совокупность подвыражений в коллекциях, но не может заставить компилятор или среду выполнения взаимодействовать!Как создать единое выражение цитаты из коллекции выражений?

Мой пример кода ниже:

[<EntryPoint>] 
let main argv = 

    let expr0 = <@ fun (r : float[]) -> r.[1] @> 
    let expr1 = <@ fun (r : float[]) -> 1.0 + r.[0] @> 
    let expr2 = <@ fun (r : float[]) -> 10.0 * r.[0] @> 
    let expr3 = <@ fun (r : float[]) -> r.[0] * r.[1] @> 
    let expr4 = <@ fun (r : float[]) -> (r.[0]-2.0)/(r.[1]-9.0) @> 

    let exprs = [|expr0; expr1; expr2; expr3; expr4|] 

    let arbInput = [|1.0; 2.0; 3.0; 4.0; 5.0|] 
    let arbOrder = [|0;4;1;3;4;2|] 

    let tree = <@ arbOrder |> Array.map (fun x -> (%(exprs.[x]) <| arbInput)) @> //cannot use the variable `x` as part of a spliced expression 
    printfn "%A" tree 

    System.Console.ReadLine() |> ignore 
    0 

Другие ошибки, полученные в других попытках принуждать это поведение включают в себя: «не может относиться к„“%» и „%%“ в качестве первого класса ...»

Я пробовал шаги, упомянутые в ответе на: Code Quotations: how to access variables of a lambda function internally?, но я не мог найти решение.

Как я могу это достичь?

ответ

2

Проблема в вашем коде заключается в том, что x является цитируемой переменной, и вы пытаетесь использовать ее значение при построении цитаты, что невозможно. Использование x не может быть в некотируемой части. Для этого вам нужно будет использовать Expr функции для создания Expr<T[]> из вашего Expr<T>[]:

let makeQuotedArray (exprs: Expr<'T>[]) : Expr<'T[]> = 
    Expr.NewArray(typeof<'T>, 
     exprs |> Array.map (fun e -> e :> Expr) |> List.ofArray) 
    |> Expr.Cast 

let exprs = makeQuotedArray [|expr0; expr1; expr2; expr3; expr4|] 

let tree = <@ arbOrder |> Array.map (fun x -> (%exprs).[x] arbInput) @>