ruxo
12/11/2016 - 1:43 AM

F# quote extraction example.

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) ] @>