SML元组-组合

SML元组-组合,sml,smlnj,Sml,Smlnj,我遇到了一个元组问题,给定一个成对元组列表,它应该变成一对列表:即[(1,2)、(3,4)、(5,6)]应该返回([1,3,5],[2,4,6]) 我已尝试使用以下代码解决此问题: fun convert L = foldl (fn(a,b) => #1a::b) [] L; 但我得到一个错误,说:未解决的flex记录。 有人能解释为什么我会得到这个,以及如何修复它吗 我手边没有SML解释器,但我想您正在寻找。尝试: IIRC,“未解决的flex记录”与记录匹配有关,而您在这里没有使用

我遇到了一个元组问题,给定一个成对元组列表,它应该变成一对列表:即
[(1,2)、(3,4)、(5,6)]
应该返回
([1,3,5],[2,4,6])

我已尝试使用以下代码解决此问题:

 fun convert L = foldl (fn(a,b) => #1a::b) [] L;
但我得到一个错误,说:未解决的flex记录。
有人能解释为什么我会得到这个,以及如何修复它吗

我手边没有SML解释器,但我想您正在寻找。尝试:


IIRC,“未解决的flex记录”与记录匹配有关,而您在这里没有使用它?!查看smlnj的错误文档(http://www.smlnj.org/doc/errors.html). 您需要搜索底部附近的错误
[99]

查看
a
,编译器可以判断它应该是一个元组(因为您正在调用
#1a
),但它无法判断它有多大。SML类型系统不允许大小未知的元组;您需要明确说明
a
是一对

虽然您可以通过给
一个
类型声明来解决这个问题,但更好的方法是进行模式匹配。不要将参数定义为
(a,b)
并使用
#1a
#2a
,而是将参数定义为
((x,y),b)
并使用
x
y

然而,您的解决方案还有另一个问题。您的函数将该对中的第一个元素添加到结果列表中,但忽略了第二个元素(
#2a
),并且您的结果缺少第二个列表。传递给
foldl
的函数应该是
fn((x,y),(u,v))=>…
,初始值应该是
([],[])


这个神秘错误消息“unresolved flex record”的原因是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公司不具备以下概念:。它知道
a
必须是一条记录,并且该记录类型必须至少包含标签
1
(以及其他可能的标签),但在SML/NJ类型系统中无法表达这一点

因此,编译器需要知道记录的确切结构,才能推断出
a
的类型,如果它不能找出它,就会抛出一个“未解析记录”错误

val it = (1,2) : int * int
- ListPair.unzip([(1,2), (3,4), (5,6)]);
> val it = ([1, 3, 5], [2, 4, 6]) : int list * int list