F# quote extraction example.
open System
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns
let rec testQuote (tab: int) (expr: Expr) =
let p = printfn "%s%s" (String(' ',tab*2))
match expr with
| Int32 i -> p <| sprintf "Int %d" i
| Double f -> p <| sprintf "Double %f" f
| String s -> p <| sprintf "String %s" s
| Call (callOnObject, methodInfo, args) ->
let callOn = match callOnObject with
| Some x -> sprintf "%A" x
| None -> "(static)"
p <| sprintf "Calling method '%s.%s': " methodInfo.Module.Name methodInfo.Name
p <| sprintf "On value: %s" callOn
p <| sprintf "With args:"
(args |> Seq.iter (testQuote <| tab+1))
| Let (var, _, body) ->
p <| sprintf "Declare %s:%A" var.Name var.Type
testQuote (tab+1) body
| Lambda (var, body) ->
p <| sprintf "Lambda expr: %s -> %s" var.Name var.Type.Name
p <| sprintf "Processing..."
testQuote (tab+1) body
| NewUnionCase (a, bodies) ->
p <| sprintf "Case %s:" a.Name
bodies |> Seq.iter (testQuote <| tab+1)
| PropertyGet (var, prop, idx) ->
printfn "var type: %A" <| var.Value.GetFreeVars()
p <| sprintf "Get %s:" prop.Name
Option.get var |> testQuote (tab+1)
if idx.Length > 0 then
p <| sprintf "With Indexes:"
idx |> Seq.iter (testQuote <| tab+1)
| _ -> p <| sprintf "Unknown expr:\n%A" expr
type A =
{ id: int
name: string }
let inner (x: bool) = x
testQuote 0 <@ fun (a:A, b:A) -> [ inner(a.id = b.id); inner(b.id = a.id); inner(a.name = b.name) ] @>