2011-04-27 53 views
1

我試圖創建一個Expr<'a -> string的手,幾個小時讀書,並努力我放棄之後創建Expr的..F# - 手工

不過,我沒弄清楚如何寫C#版本:

let buildExpression<'a> = 
    let p = E.Parameter(typeof<'a>) 
    E.Lambda<F<'a,string>>(p) 

這將產生:

Expression<Func<'a, string>>

所以我的問題是,我該如何使用創建模塊?

回答

2

C#示例有點可疑,如果您調用buildExpression<int>,那麼結果將會是一個表達式(在C#sytnax中):Func<int, string>(x => x),它有一個錯誤的類型。我猜C#不會在構造時檢查類型,但如果你嘗試編譯它,它可能會崩潰。

我想你想要建立類似x => x.Foo的東西。然後下面的片段應該做的伎倆:

open Microsoft.FSharp.Quotations 

type Foo() = 
    member x.Prop = "hello" 

// Create a new variable 'x' 
let arg = Var.Global("x", typeof<Foo>) 
// Use Reflection to get information about the 'Prop' member 
let propInfo = typeof<Foo>.GetProperty("Prop") 
// Create a lambda 'fun x -> x.Prop' 
let e = Expr.Lambda(arg, Expr.PropertyGet(Expr.Var(arg), propInfo)) 
+0

完美! 'e'將在你的例子中返回'Expr',我將如何返回'Expr string>'而不是? – ebb 2011-04-27 16:41:42

+2

'Expr.Cast'應該這樣做。但要小心!您可以將'<@@ 4 @@>'轉換爲'Expr ',並且僅在運行時(而不是在編譯期間)出現錯誤。 – 2011-04-27 17:04:54