Skip to content

Instantly share code, notes, and snippets.

@Thorium
Created November 8, 2019 14:11
Show Gist options
  • Save Thorium/7c4a884e9f1c078487ba5ec7b7143188 to your computer and use it in GitHub Desktop.
Save Thorium/7c4a884e9f1c078487ba5ec7b7143188 to your computer and use it in GitHub Desktop.
F# LINQ-Expression-tree visitor
// A simple expression tree visitor, to inject a lambda inside another lambda parameters.
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment