4 people like it.

F# LINQ-Expression-tree visitor

A simple expression tree visitor, to inject a lambda inside another lambda parameters.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
open Microsoft.FSharp.Linq.RuntimeHelpers
open System
open System.Linq.Expressions

//F#-helper method for Linq.Expressions: fssnip.net/ts/title/F-lambda-to-C-LINQ-Expression
module Lambda =
    let toExpression (``f# lambda`` : Quotations.Expr<'a>) =
        ``f# lambda``
        |> LeafExpressionConverter.QuotationToExpression 
        |> unbox<Expression<'a>>

let toTraverse = <@ Func<int, int>(fun i -> i + 1) @> |> Lambda.toExpression 
// val toTraverse : Expression<Func<int,int>> = i => (i + 1)

let toInject = <@ Func<int, int>(fun j -> j * 2) @> |> Lambda.toExpression
// val toInject : Expression<Func<int,int>> = j => (j * 2)

let visitor =
    { new ExpressionVisitor() with
        member __.VisitParameter _ = toInject.Body
        member __.VisitLambda x =
            let visitedBody = base.Visit x.Body
            Expression.Lambda(visitedBody, toInject.Parameters) :> Expression
        }
let visited = visitor.Visit toTraverse
// val visited : Expression = j => ((j * 2) + 1)

//let f = Expression.Lambda(visited).Compile().DynamicInvoke() |> unbox<Func<int,int>>
//f.Invoke(5) // val it : int = 11
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Linq
namespace Microsoft.FSharp.Linq.RuntimeHelpers
namespace System
namespace System.Linq
namespace System.Linq.Expressions
val toExpression : f# lambda:Quotations.Expr<'a> -> Expression<'a>

Full name: Script.Lambda.toExpression
val ( f# lambda ) : Quotations.Expr<'a>
namespace Microsoft.FSharp.Quotations
Multiple items
type Expr =
  override Equals : obj:obj -> bool
  member GetFreeVars : unit -> seq<Var>
  member Substitute : substitution:(Var -> Expr option) -> Expr
  member ToString : full:bool -> string
  member CustomAttributes : Expr list
  member Type : Type
  static member AddressOf : target:Expr -> Expr
  static member AddressSet : target:Expr * value:Expr -> Expr
  static member Application : functionExpr:Expr * argument:Expr -> Expr
  static member Applications : functionExpr:Expr * arguments:Expr list list -> Expr
  ...

Full name: Microsoft.FSharp.Quotations.Expr

--------------------
type Expr<'T> =
  inherit Expr
  member Raw : Expr

Full name: Microsoft.FSharp.Quotations.Expr<_>
module LeafExpressionConverter

from Microsoft.FSharp.Linq.RuntimeHelpers
val QuotationToExpression : Quotations.Expr -> Expression

Full name: Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToExpression
val unbox : value:obj -> 'T

Full name: Microsoft.FSharp.Core.Operators.unbox
Multiple items
type Expression =
  member CanReduce : bool
  member NodeType : ExpressionType
  member Reduce : unit -> Expression
  member ReduceAndCheck : unit -> Expression
  member ReduceExtensions : unit -> Expression
  member ToString : unit -> string
  member Type : Type
  static member Add : left:Expression * right:Expression -> BinaryExpression + 1 overload
  static member AddAssign : left:Expression * right:Expression -> BinaryExpression + 2 overloads
  static member AddAssignChecked : left:Expression * right:Expression -> BinaryExpression + 2 overloads
  ...

Full name: System.Linq.Expressions.Expression

--------------------
type Expression<'TDelegate> =
  inherit LambdaExpression
  member Compile : unit -> 'TDelegate + 1 overload
  member Update : body:Expression * parameters:IEnumerable<ParameterExpression> -> Expression<'TDelegate>

Full name: System.Linq.Expressions.Expression<_>
val toTraverse : Expression<Func<int,int>>

Full name: Script.toTraverse
Multiple items
type Func<'TResult> =
  delegate of unit -> 'TResult

Full name: System.Func<_>

--------------------
type Func<'T,'TResult> =
  delegate of 'T -> 'TResult

Full name: System.Func<_,_>

--------------------
type Func<'T1,'T2,'TResult> =
  delegate of 'T1 * 'T2 -> 'TResult

Full name: System.Func<_,_,_>

--------------------
type Func<'T1,'T2,'T3,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 -> 'TResult

Full name: System.Func<_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 -> 'TResult

Full name: System.Func<_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'TResult

Full name: System.Func<_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'T16,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val i : int
module Lambda

from Script
val toInject : Expression<Func<int,int>>

Full name: Script.toInject
val j : int
val visitor : ExpressionVisitor

Full name: Script.visitor
Multiple items
type ExpressionVisitor =
  member Visit : node:Expression -> Expression + 1 overload
  member VisitAndConvert<'T> : node:'T * callerName:string -> 'T + 1 overload
  static member Visit<'T> : nodes:ReadOnlyCollection<'T> * elementVisitor:Func<'T, 'T> -> ReadOnlyCollection<'T>

Full name: System.Linq.Expressions.ExpressionVisitor

--------------------
ExpressionVisitor() : unit
property LambdaExpression.Body: Expression
val __ : ExpressionVisitor
ExpressionVisitor.VisitLambda<'T>(node: Expression<'T>) : Expression
val x : Expression<'a>
val visitedBody : Expression
Expression.Lambda(body: Expression, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(body: Expression, [<ParamArray>] parameters: ParameterExpression []) : LambdaExpression
   (+0 other overloads)
Expression.Lambda<'TDelegate>(body: Expression, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : Expression<'TDelegate>
   (+0 other overloads)
Expression.Lambda<'TDelegate>(body: Expression, [<ParamArray>] parameters: ParameterExpression []) : Expression<'TDelegate>
   (+0 other overloads)
Expression.Lambda(body: Expression, name: string, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(delegateType: Type, body: Expression, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(delegateType: Type, body: Expression, [<ParamArray>] parameters: ParameterExpression []) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(body: Expression, tailCall: bool, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(body: Expression, tailCall: bool, [<ParamArray>] parameters: ParameterExpression []) : LambdaExpression
   (+0 other overloads)
Expression.Lambda<'TDelegate>(body: Expression, name: string, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : Expression<'TDelegate>
   (+0 other overloads)
property LambdaExpression.Parameters: Collections.ObjectModel.ReadOnlyCollection<ParameterExpression>
val visited : Expression

Full name: Script.visited
ExpressionVisitor.Visit(nodes: Collections.ObjectModel.ReadOnlyCollection<Expression>) : Collections.ObjectModel.ReadOnlyCollection<Expression>
ExpressionVisitor.Visit(node: Expression) : Expression
Raw view Test code New version

More information

Link:http://fssnip.net/7Xg
Posted:4 years ago
Author:Tuomas Hietanen
Tags: expression , linq