如何解决SML Create函数接收元组列表,并返回每对和的列表
我正在研究Standard ML,我要做的一项练习是编写一个名为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
ATTEMPT 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}
解决方法
第一次尝试有一个错字:定义了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
也是一个空列表:然后,将各个元组总和限制到该空列表中以创建输出列表。
要扩展exnihilo的答案,一旦您熟悉使用显式递归和模式匹配(opPairs ((a,b)::cs) = ...
)的解决方案类型,就可以开始使用列表组合器来概括该解决方案了:
val opPairs = map op+
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。