How to convert Expr <'a ->' b> into an expression <Func <'a, obj >>

I am using F # 3.0 with beta version of .NET 4.5, and I am trying to convert an F # type quote Expr<'a -> 'b>to LINQ Expression<Func<'a, 'b>>.

I found several questions that have solutions to this problem, but these methods no longer work, probably due to changes in F # 3.0 or .NET 4.5.

In both cases, when I run the code from solutions to any question, the following action throws an exception:

mc.Arguments.[0] :?> LambdaExpression

... where mcis MethodCallExpression. The exception is:

System.InvalidCastException: "System.Linq.Expressions.MethodCallExpressionN" "System.Linq.Expressions.LambdaExpression".

, "N" MethodCallExpressionN . - ? .

UPDATE

. , <@ fun x -> x + 1 @>. , Expr<'a -> 'b> Expr<'a -> obj>, - box. , : <@ %exp >> box @>. , Expression<Func<'a, obj>> .

module Expr =
    open System
    open System.Linq.Expressions
    open Microsoft.FSharp.Quotations
    open Microsoft.FSharp.Linq.QuotationEvaluation

    let rec private translateExpr (linq:Expression) = 
        match linq with
        | :? MethodCallExpression as mc ->
            let le = mc.Arguments.[0] :?> LambdaExpression
            let args, body = translateExpr le.Body
            le.Parameters.[0] :: args, body
        | _ -> [], linq

    let ToFuncExpression (expr:Expr<'a -> 'b>) = 
        let args, body = expr.ToLinqExpression() |> translateExpr 
        Expression.Lambda<Func<'a, 'b>>(body, Array.ofList args) 

let exp = <@ fun x -> x + 1 @>

let r = Expr.ToFuncExpression <@ %exp >> box @>
printfn "%A" r
+5
1

, F #, ?

.NET 4.5 , . :

  • F # 3.0 Linq.fs Linq.fsi 2.0 F # PowerPack. ( 3.0 ToLinqExpression, - F # 3.0?)

  • :

    let r = toLinq <@ fun x -> x + 1 @>
    printfn "%A" r
    

    x => (x + 1), .

: - , ( ), , , : <@ fun x -> ... @>.

, . :

let exp = <@ fun x -> x + 1 @> 
let r = toLinq <@ fun a -> box ((%exp) a) @> 
printfn "%A" r

F #, Expression ToFSharpFunc ( F #), . , Expression, .NET ( # ).

+4

All Articles