SML记录子集和更新

时间:2014-07-24 00:13:16

标签: sml

是否有更直接的方式(并且由于维护和涉及的编辑量而更不容易出错),以实现与下面相同的方法,即:1)获取记录元素的子集,给定名称感兴趣的成员列表,2)并使用子集记录的名称更新子集记录中的记录?

val r = {a = 1, b = 2, c = 3, d = 4, e = 5}
val s = {b = #b r, c = #c r, d = #d r}
val r = {a = #a r, b = #b s, c = #c s, d = #d s, e = #e r}

我的期望,看起来像这样:

val r = {a = 1, b = 2, c = 3, d = 4, e = 5}
val s = #(b, c, d) r
val r = r / s

正如SebastianPaaskeTørhol所说,人们可以通过这种方式提取部分记录:

val {b, c, d, ...} = r

不幸的是,这并没有将子集绑定到单个名称,因为这个例子不起作用:

val s = {b, c, d, ...} = r

2 个答案:

答案 0 :(得分:4)

您可以使用模式匹配来提取记录的相关部分:

示例:

val question = { title = "SML record subset and update",
                 author = "Hibou57",
                 tags = ["SML"] }

val { title = t, tags = ts, ... } = question

这会将标题绑定到t并将标签绑定到ts

如果您愿意,也可以简单地省略名称:

val { title, tags, ... } = question

这会将标题绑定到title,将标签绑定到tags

就更新而言,标准ML遗憾地没有一种很好的方法来更新记录而不必明确地设置每个字段。

答案 1 :(得分:4)

不,没有。曾经提出过更广泛的记录操作(Functional record extension and row capture),作为短期继任ML工作的一部分。有了这个,你可以写,例如,

val r = {a = 1, b = 2, c = 3, d = 4, e = 5}
val {a, e, ... = s} = r
val t = {a = a+1, e = e-1, ... = s}

不幸的是,没有人在真正的编译器中实现它。