2017-02-17 42 views
2

有人可以幫我寫一篇Tomas Petricek的文章:http://tomasp.net/blog/fsharp-dynamic-lookup.aspx/#dynfslinks? 問題是它嚴重過時。我知道命名空間F中的動態查詢#

open Microsoft.FSharp.Quotations.Typed 
open Microsoft.FSharp.Quotations.Raw 

都沒有了。所以我刪除了開口。但仍有錯誤。 「類型」未定義。 「RecdGet」未定義。我懷疑他們不是最後一個。我試圖向我的老闆證明F#可以很好地用於數據庫規範化。字段的動態查找將幫助我處理具有不同前綴的名稱相似的字段。

還有對fpish托馬斯的崗位:https://fpish.net/topic/None/57493,我的理解早文章

+1

您正在尋找這樣的事情? http://stackoverflow.com/questions/17640218/accessing-dynamic-property-in-f – mydogisbox

+1

@mydogisbox,是的,但我想訪問被靜態檢查。所以,如果屬性不存在,我會得到編譯錯誤。據我瞭解,托馬斯的解決方案就是這樣做的。 – alehro

回答

3

這裏有一個大致相當於:

open Microsoft.FSharp.Quotations 
open Microsoft.FSharp.Quotations.Patterns 

type DynamicMember<'t,'u> = Expr<'t -> 'u> 

let getValueReader (expr:DynamicMember<'recdT, 'fieldT>) = 
    // Match the quotation representing the symbol 
    match expr with 
    | Lambda(v, PropertyGet (Some (Var v'), pi, [])) when v = v' -> 
     // It represents reading of the F# record field.. 
     // .. get a function that reads the record field using F# reflection 
     let rdr = Reflection.FSharpValue.PreComputeRecordFieldReader pi 

     // we're not adding any additional processing, so we just 
     // simply add type conversion to the correct types & return it 
     ((box >> rdr >> unbox) : 'recdT -> 'fieldT) 
    | _ -> 
     // Quotation doesn't represent symbol - this is an error 
     failwith "Invalid expression - not reading record field!" 

type SampleRec = { Str : string; Num : int } 

let readStrField = getValueReader <@ fun (r : SampleRec) -> r.Str @> 
let readNumField = getValueReader <@ fun (r : SampleRec) -> r.Num @> 

let rc = { Str = "Hello world!"; Num = 42 } 
let s, n = readStrField rc, readNumField rc 

printfn "Extracted: %s, %d" s n