5

我一直在尝试创建一个以元组列表作为参数的函数,但我不断收到错误消息:“未解析的弹性记录(需要知道此上下文中所有字段的名称)”我的代码是:

fun convert d = ( (map (#1) d) , (map (#2) d) );

这基本上是试图将一对列表转换为一对列表。我也尝试声明das的类型,:('a * 'b) list但这导致了更多错误。我认为这与元组的未知大小有关,并且可以使用一些帮助来使其知道。

4

1 回答 1

5

我怀疑您在注释类型时遇到的问题d实际上只是您没有用括号包围注释,这对我有用:

fun convert (d : ('a * 'b) list) = ( (map (#1) d) , (map (#2) d) )

然而,这不是很好的 SML 风格。不鼓励使用#1,等#2#n因为它会导致这样的问题,在这种情况下,您已经失去了类型推断为您提供的一些通常的简洁性。

相反,您可以为对定义一些显式选择函数:

fun first  (a, _) = a
fun second (_, b) = b

fun convert d = (map first d, map second d)

(请注意,我还从 的主体中删除了一些多余的括号convert,因为函数应用程序具有比元组构造更高的优先级,并且我还删除了分号,这仅在对命令式代码进行排序或将代码键入时才真正需要REPL)

是一个非常好的标准 ML 风格指南,来自哈佛(或者可能是塔夫茨大学)的一门课程。该文档的旧版本在“要避免的常见错误”下特别提到了这一点。

避免 #1 和 #2

一些初学者接受这样的想法,即获得一对中第二个元素的好方法p是写作#2 p

这种风格不是惯用的或可读的,它会混淆类型检查器。处理对的正确方法是通过模式匹配,所以

fun first (x, _) = x
fun second (_, y) = y

是首选,而不是

fun bogus_first p = #1 p (* WRONG *)
fun bogus_second p = #2 p

(出于我不想讨论的原因,这些版本甚至不进行类型检查。)

如果您的对或元组不是函数的参数,请使用val进行模式匹配:

val (x, y) = lookup_pair mumble

但通常您可以将匹配包含在普通的有趣匹配中。

于 2013-01-02T22:07:33.633 回答