我遇到了一个元组问题,在给定一个元组对列表的情况下,它应该变成一对列表:即[(1,2),(3,4),(5,6)]应该返回([1,3,5],[2,4,6])。
我试着用下面的代码解决这个问题:
fun convert L = foldl (fn(a,b) => #1a::b) [] L;但是我得到了一个错误:未解析的flex记录。有没有人能解释一下为什么我会得到这个问题,以及如何修复它?
发布于 2012-03-24 11:03:35
查看a,编译器可以告诉您它应该是一个元组(因为您调用的是#1a),但是它不能告诉它有多大。SML类型系统不允许未知大小的元组;您需要明确a是一个对。
虽然您可以通过给a一个类型声明来解决这个问题,但更好的方法是对其进行模式匹配。不要将参数定义为(a,b)并使用#1a和#2a,而是将参数定义为((x,y),b)并使用x和y。
然而,您的解决方案还有另一个问题。您的功能是将该对中的第一个元素添加到结果列表中,但是忽略了第二个元素(#2a),并且您的结果缺少第二个列表。传递给foldl的函数应该是fn ((x,y),(u,v)) => ...,初始值应该是([],[])。
这条隐秘的错误消息“未解析的flex记录”的原因是,SML中的元组被实现为具有整数标签的记录。元组(a,b)与记录{1=a,2=b}相同。实际上,如果您在SML/NJ shell中键入{1=1,2=2},它将返回
val it = (1,2) : int * int因此,当您说#1a时,实际上是在说“从记录a中提取标签为1的元素”。
SML/NJ没有record polymorphism的概念。它理解a必须是一条记录,并且该记录类型必须至少包含标签1 (以及可能的其他标签),但是在SML/NJ类型系统中无法表达这一点。
因此,编译器需要知道记录的确切结构才能推断出a的类型,如果不能确定,就会抛出一个“未解析的记录”错误。
发布于 2012-03-24 04:20:52
我手头没有一个SML解释器,但我认为你正在寻找unzip。尝试:
unzip([(1,2), (3,4), (5,6)]);IIRC,“未解析的flex记录”与记录匹配有关,而您在这里没有使用它?!看看smlnj (http://www.smlnj.org/doc/errors.html)的错误文档。您将需要搜索底部附近的error [99]。
发布于 2016-03-02 02:59:50
- ListPair.unzip([(1,2), (3,4), (5,6)]);
> val it = ([1, 3, 5], [2, 4, 6]) : int list * int listhttps://stackoverflow.com/questions/9845654
复制相似问题