2013-06-07 9 views
5

のようなF#のレコードをループ、私はループのためにシンプルなオブジェクトのすべてのプロパティにアクセスすることができます。はJavascriptオブジェクトJavaScriptで

type MyObj = {x:int; y:int} 
let myObj = {x=1; y=2} 
let allValues:seq<int> = allPropertyValuesIn myObj //How do I implement allPropertyValuesIn 
let sum = allValues |> Seq.fold (+) 0 

私はXMLファイル生成に取り組んでいますそのようなこと
をやりたい理由を明確にするために、あなたの入力のための

編集ありがとうございました。入力はデータベースから読み取られた行で、xsdは事前定義されています。

"Product"要素を生成する必要があり、ビジネスルールによっては、製品の下に200個のChildren要素が必要な場合があります。一部は必須で、一部はオプションです。これは非常に退屈で非簡潔である

1. type Product{ Price:Money; Name:Name; FactoryLocation:Address option ... } 
2. let product = {Price = Money(1.5); Name = Name ("Joe Tooth Paste"); ... } 
3. let child1 = createEl ("Price", product.Price) 
    .. 
203. let allChildren = child1 
         ::child2 
         ::child3 
         .. 
         ::[] 
404. let prodctEl = createElWithCildren ("Product", allChildren) 

this excellent blogからのアドバイスに続いて、私は、製品レコードのための私の最初の(非常に粗い)のデザインを持っていました。 F#でこのようなことをするより良い方法が必要です。私は反射のアイデアにも親しみがありません。

他の方法がありますか、それとも間違っていますか?

+2

これは反映されても可能ですが、高速でタイプセーフな代替手段は存在しません。 –

+0

"Edit to clarify why ..."という問題が大きく変わった:/チャイルド構造を自動化するには、チャイルド構造(200個のチャイルド構造)をNORMALIZEする必要があります。 – josejuan

答えて

5

これを試してみてください:ジョン・パーマーが訓戒として

open Microsoft.FSharp.Reflection 

type MyObj = {x:int; y:int} 
let myObj = {x=1; y=2} 
let allValues = FSharpType.GetRecordFields (myObj.GetType()) 
let sum = 
    allValues 
    |> Seq.fold 
     (fun s t -> s + int(t.GetValue(myObj).ToString())) 
     0 
printfn "%d" sum 

しかし、このような何かを行うために非常に多くの良い理由がありません。

+2

これはその良い理由の一つです。構造体/レコードをマップ(データ構造体、実際は構造体)のように扱うことは、パブリックインタフェースで型チェッカーを最大限に活用するのに便利です。レコードを使用して、可能なすべてのパラメータをWeb APIに表示できます(必要に応じてOptionタイプを含む)。その後、httpペイロードを構築するためにメンバー名の壁を書く代わりに、このようなことをします。ウォール・オブ・ネームのアプローチは、保守性に特に悪いものです。 – Cogwheel

関連する問題