2017-02-17 4 views
2

Kann mir jemand mit Artikel von Tomas Petricek helfen: http://tomasp.net/blog/fsharp-dynamic-lookup.aspx/#dynfslinks? Das Problem ist, dass es stark veraltet ist. Ich verstehe, dass NamespacesDynamische Suche in F #

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

sind weg. Also habe ich die Öffnungen entfernt. Aber es gibt immer noch Fehler. "Getippt" ist nicht definiert. "RecdGet" ist nicht definiert. Und ich vermute, dass sie nicht die Letzten sind. Ich versuche meinem Chef zu beweisen, dass F # gut für die Datenbanknormalisierung ist. Die dynamische Suche nach Feldern würde mir sehr dabei helfen, ähnlich benannte Felder mit unterschiedlichen Präfixen zu bearbeiten.

Es gibt auch Post von Tomas auf fpish: https://fpish.net/topic/None/57493, das verstehe ich schon vor dem Artikel

+1

Suchen Sie so etwas? http://stackoverflow.com/questions/17640218/accessing-dynamic-property-in-f – mydogisbox

+1

@mydogisbox, Ja, aber ich möchte den Zugriff statisch überprüft werden. Also, wenn die Eigenschaft nicht existiert, bekomme ich einen Kompilierungsfehler. Soweit ich weiß, macht die Lösung von Tomas das. – alehro

Antwort

3

Hier ist eine grobe Entsprechung:

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 
Verwandte Themen