我一直在尝试使用元组列表作为参数创建一个函数,但我不断收到错误:“未解析的flex记录(需要知道此上下文中所有字段的名称)”< / em>我的代码是:
fun convert d = ( (map (#1) d) , (map (#2) d) );
这是基本上尝试将对列表转换为一对列表。我还尝试将d
的类型声明为:('a * 'b) list
,但这导致了更多错误。
我认为这与tupple的未知大小有关,可以使用一些帮助来了解它。
答案 0 :(得分:5)
我怀疑您在注释d
类型时遇到的问题实际上只是因为您没有用parens包围注释,这对我有用:
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中键入代码时真的很有必要
This是标准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
但通常你可以在普通的有趣匹配中包含匹配。