Functional programming SML Create函数接收元组列表和返回列表,每个元组对求和

Functional programming SML Create函数接收元组列表和返回列表,每个元组对求和,functional-programming,sml,Functional Programming,Sml,我正在学习标准ML,我必须做的一个练习是编写一个名为opPairs的函数,它接收int类型的元组列表,并返回一个包含每对元组之和的列表。 例如: 这些是我的尝试,但没有编译: 尝试1 type T0 = int * int; fun opPairs ((h:TO)::t) = let val aux =(#1 h + #2 h) in aux::(opPairs(t)) end; Th

我正在学习标准ML,我必须做的一个练习是编写一个名为opPairs的函数,它接收int类型的元组列表,并返回一个包含每对元组之和的列表。 例如:

这些是我的尝试,但没有编译:

尝试1

type T0 = int * int;
fun opPairs ((h:TO)::t) = let val aux =(#1 h + #2 h) in
                              aux::(opPairs(t))
                         end;

The error message is:
Error: unbound type constructor: TO
Error: operator and operand don't agree [type mismatch]
  operator domain: {1:'Y; 'Z}
  operand:         [E]
  in expression:
    (fn {1=1,...} => 1) h
尝试2

fun opPairs2 l = map (fn x => #1 x + #2 x ) l;

The error message is: Error: unresolved flex record (need to know the names of ALL the fields
 in this context)
  type: {1:[+ ty], 2:[+ ty]; 'Z}

第一次尝试有一个输入错误:
类型T0
已定义,其中
0
为零,但模式中引用类型
TO
,其中
O
为字母O。这消除了“操作数和运算符不一致”错误,但还有一个问题。模式
((h:T0)::t)
与空列表不匹配,因此存在一个带有更正类型标识符的“match nonexhoustive”警告。这在使用函数时表现为异常,因为代码到达输入末尾时需要匹配空列表

第二次尝试需要为元组使用类型。这是因为元组访问器需要知道它访问的元组的类型。要解决此问题,请向匿名函数提供元组参数的类型:

fun opPairs2 l = map (fn x:T0 => #1 x + #2 x) l;
但是,使用
#1
#2
等访问元组字段实际上是一种不好的做法;改用模式匹配。这是一种更干净的方法,更像第一次尝试,但充分利用了模式匹配:

fun opPairs nil = nil
  | opPairs ((a, b)::cs) = (a + b)::(opPairs cs);

这里,
opPairs
在输入为空列表时返回一个空列表,否则模式匹配将提供字段值
a
b
,以递归方式添加并使用到输出中。当到达最后一个元组时,
cs
是空列表,
opPairs cs
也是空列表:然后将各个元组和消耗到此空列表上以创建输出列表。

扩展exnihilo的回答,一旦您熟悉了使用显式递归和模式匹配的解决方案类型(
opPairs((a,b)::cs)=……
),您就可以开始使用列表组合器来概括解决方案:

val opPairs = map op+
val opPairs = map op+