SML Create 函数接收元组列表并返回带有每对总和的列表

Kat*_*ten 2 functional-programming sml

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

input: opPairs [(1, 2), (3, 4)]
output: val it = [3, 7]
Run Code Online (Sandbox Code Playgroud)

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

尝试 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
Run Code Online (Sandbox Code Playgroud)

尝试 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}
Run Code Online (Sandbox Code Playgroud)

ex *_*ilo 5

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

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

fun opPairs2 l = map (fn x:T0 => #1 x + #2 x) l;
Run Code Online (Sandbox Code Playgroud)

但是,真的是不好的做法,使用#1#2等访问元组领域; 改用模式匹配。这是一种更简洁的方法,更像是第一次尝试,但充分利用了模式匹配:

fun opPairs nil = nil
  | opPairs ((a, b)::cs) = (a + b)::(opPairs cs);
Run Code Online (Sandbox Code Playgroud)

这里,opPairs当输入是空列表时返回一个空列表,否则模式匹配提供字段值ab递归地添加和consed到输出上。当到达最后一个元组时,cs它是空列表,opPairs cs然后也是空列表:然后将单个元组总和放入此空列表以创建输出列表。