Sam
Sam

Reputation: 2875

How do I programmatically build up the following Quotation Expression in F#?

I have a need to access a .NET dictionary within a quotation expression. The following is a simplified version:

let mutable dict:Dictionary<string, float> = Dictionary()
dict.Add("first", 1.0)
dict.Add("second", 2.0)
let qe2 = <@ dict.["second"] @>

The output of qe2 is as follows:

val qe2 : Quotations.Expr<float> =
PropertyGet (Some (PropertyGet (None, dict, [])), Item, [Value ("second")])

All is fine when I can directly create the quotation expression directly with quoted code as above. How do I achieve the same thing by building up qe2 programmatically?

I know that I need to somehow use Quotations.Expr.PropertyGet twice in a nested fashion but I don't know how to obtain the neccesary PropertyInfo and MethodInfo objects to go about doing that.

Upvotes: 1

Views: 228

Answers (1)

Wallace
Wallace

Reputation: 17488

The key is to know that the let dict declaration is compiled as a property on the static module class.

Here is a working sample.

module QuotationsTest

open Microsoft.FSharp.Quotations
open System
open System.Collections.Generic
open System.Reflection

let mutable dict:Dictionary<string, float> = Dictionary()
dict.Add("first", 1.0)
dict.Add("second", 2.0)
let qe2 = <@ dict.["second"] @>

let moduleType = Type.GetType("QuotationsTest")
let dictProp = moduleType.GetProperty("dict", BindingFlags.Static ||| BindingFlags.Public)   
let indxProp = dict.GetType().GetProperty("Item", [| typeof<string> |])
let qe1 = Expr.PropertyGet(Expr.PropertyGet(dictProp, []), indxProp, [ Expr.Value("first") ])

printfn "%A" qe1
printfn "%A" qe2

Compiling and running the above results in the following:

> fsc QuotationsTest.fs
Microsoft (R) F# Compiler version 12.0.30815.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

> QuotationsTest.exe
PropertyGet (Some (PropertyGet (None, dict, [])), Item, [Value ("first")])
PropertyGet (Some (PropertyGet (None, dict, [])), Item, [Value ("second")])

Upvotes: 7

Related Questions