我一直在尝试创建一个以元组列表作为参数的函数,但我不断收到错误消息:“未解析的弹性记录(需要知道此上下文中所有字段的名称)”我的代码是:
fun convert d = ( (map (#1) d) , (map (#2) d) );
这基本上是试图将一对列表转换为一对列表。我也尝试声明d
as的类型,:('a * 'b) list
但这导致了更多错误。我认为这与元组的未知大小有关,并且可以使用一些帮助来使其知道。
我一直在尝试创建一个以元组列表作为参数的函数,但我不断收到错误消息:“未解析的弹性记录(需要知道此上下文中所有字段的名称)”我的代码是:
fun convert d = ( (map (#1) d) , (map (#2) d) );
这基本上是试图将一对列表转换为一对列表。我也尝试声明d
as的类型,:('a * 'b) list
但这导致了更多错误。我认为这与元组的未知大小有关,并且可以使用一些帮助来使其知道。
我怀疑您在注释类型时遇到的问题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
但通常您可以将匹配包含在普通的有趣匹配中。