我正在学习Standard,我需要做的一个练习是编写一个名为opPairs的函数,它接收一个int类型的元组列表,并返回一个包含每对的和的列表。示例:
input: opPairs [(1, 2), (3, 4)]
output: val it = [3, 7]这些都是我的尝试,并不是在汇编:
尝试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}发布于 2020-08-11 00:45:02
第一次尝试有一个错误:定义了type T0,其中0为零,但是在模式中引用了TO类型,其中O是字母O,这消除了“操作数和操作符不同意”的错误,但是还有一个进一步的问题。模式((h:T0)::t)不匹配空列表,因此有一个“匹配非详尽”警告,并带有更正的类型标识符。当使用函数时,这会显示为异常,因为当代码到达输入的末尾时,需要匹配一个空列表。
第二次尝试需要为元组使用类型。这是因为元组访问器#n需要知道它访问的元组的类型。要解决此问题,请向匿名函数提供元组参数的类型:
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也是空列表:然后将单个元组和转换到这个空列表中,以创建输出列表。
发布于 2020-08-12 16:36:05
为了扩展兴奋感的答案,一旦您熟悉了使用显式递归和模式匹配(opPairs ((a, b)::cs) = ...)的解决方案类型,就可以开始使用列表组合器来概括解决方案:
val opPairs = map op+https://stackoverflow.com/questions/63349382
复制相似问题