循环遍历F#记录,如Javascript对象

Wei*_* Ma 5 f#

在javascript中,我可以使用简单的for循环访问对象的每个属性,如下所示

var myObj = {x:1, y:2};
var i, sum=0;
for(i in myObj) sum = sum + myObj[i];
Run Code Online (Sandbox Code Playgroud)

我想知道我是否可以用F#做类似的事情.

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
Run Code Online (Sandbox Code Playgroud)

谢谢您的意见

编辑以澄清我为什么要做这样的事情
我正在研究XML文件生成器.输入是从数据库读取的行,xsd是预定义的.

假设我需要生成"产品"元素,并且根据业务规则,产品下可能有200个子元素,有些是必需的,有些是可选的.根据这个优秀博客的建议,我有第一个(非常粗略)的产品记录设计:

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)
Run Code Online (Sandbox Code Playgroud)

这非常繁琐且不简洁.在F#中有更好的方法来做这样的事情.我对反思的想法也不是很了解.

有没有其他方法或我只是做错了?

Shr*_*roy 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
Run Code Online (Sandbox Code Playgroud)

然而,正如约翰帕尔默所劝告的那样,做这样的事情的理由并不是很多.

  • 这是其中一个很好的理由.像地图一样处理结构/记录(数据结构,实际上是结构体)对于在公共接口中充分利用类型检查器非常有用.您可以使用记录来表示Web api的所有可能参数(包括适当的选项类型).然后在幕后,做这样的事情而不是写一个成员名墙来构建http有效载荷.名称墙法对可维护性特别不利. (3认同)