未解决的弹性记录(需要知道此上下文中所有字段的名称)

时间:2012-11-21 16:00:02

标签: pattern-matching tuples smlnj

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

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

这是基本上尝试将对列表转换为一对列表。我还尝试将d的类型声明为:('a * 'b) list,但这导致了更多错误。 我认为这与tupple的未知大小有关,可以使用一些帮助来了解它。

1 个答案:

答案 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
     

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