SML记录子集和更新

SML记录子集和更新,sml,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

是否有一种更直接的方法(并且由于维护和涉及的编辑量而不容易出错)来实现以下相同的目的,即: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
正如Sebastian Paaske Tørhol所说,可以通过以下方式提取部分记录:

val {b, c, d, ...} = r
不幸的是,这不会将子集绑定到单个名称,例如,这不起作用:

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

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

例如:

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

val { title = t, tags = ts, ... } = question
这会将标题绑定到
t
,并将标签绑定到
ts

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

val { title, tags, ... } = question
这会将标题绑定到
标题
,将标记绑定到
标记


就更新而言,不幸的是,标准ML没有一种在不明确设置每个字段的情况下更新记录的好方法。

不,没有。曾经有人提议进行更广泛的记录操作(),作为短期后续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}

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

我不知道模式匹配可以通过这种方式用于记录。谢谢你的提示。我会在选择这个答案之前等待,只是等待是否有人愉快地对更新部分有想法。这个“…”是如何命名的?我以前从未见过它,而且它似乎是必需的,而不仅仅是代码片段中的占位符。一个问题是:虽然这提取了记录的一部分,但这无法将此子集绑定到单个名称。回答我自己:“…”只是根据其通用名称命名的,即省略号(SML没有给它任何专用名称)。有些内容与功能记录类型和子类型有关,命名为System 有趣的是,子类型化为语言带来了一个全新的复杂性和问题维度,特别是当与多态性结合时,如F-sub和扩展。几十年来,它一直困扰着OO类型的系统,而在函数式语言中,您通常不希望出现这种情况。一个更好的选择是行多态性,它至少允许实际的类型推断。困扰OO的是缺乏真正的形式化和形式化方法:它没有在无法正确处理的地方停止。否则,我同意你的观点,如果这更复杂,那么实现安全性也更复杂(但并非不可能,如果我没有错,这一逻辑是合理的)。谢谢你的评论。嗯,已经有很多形式化的评论了。但子类型是一个兔子洞——看看Abadi&Cardelli,或者看看Scala,看看它有多复杂。F-omega-sub的某些版本已经无法确定。与参数多态性相比,所有这些对于表达能力的提升都相当微弱。我可能不太理解子类型在形式上是什么。