给定一个数字列表,我想创建一个新列表,其中索引为i
的元素
是之前所有i-1
元素的总和。
例如:
[1,4,6,9] -> [1,5,11,20]
我写了以下代码:
fun sum nil = 0
| sum [x]=x
| sum(x::rest)=(x+hd(rest))::sum(rest);
但我得到了这个:
- fun sum nil = 0
= | sum [x]=x
= | sum(x::rest)=(x+hd(rest))::sum(rest);
stdIn:306.16-306.39 Error: operator and operand don't agree [literal]
operator domain: int * int list
operand: int * int
in expression:
x + hd rest :: sum rest
我可以看到(x+hd(rest))::sum(rest);
的递归规则是其中的原因
问题,但我该如何解决?
此致
答案 0 :(得分:5)
查看您的基本案例。您希望函数返回一个列表,因此基本案例应返回列表。
fun sum [] = []
| sum [x] = [x]
| sum (x::xs) = ...
我将nil
替换为[]
,因为我更喜欢它 - 这并不重要。
另一件事 - 永远不要使用hd
和tl
运算符(有例外,但就目前而言,只是不这样做)。当然,在你的功能中,它不会成为一个问题,因为你照顾的情况,但还有另一个原因。如果你这样做:
fun foo [] = ...
| foo (x::y::xs) = ...
SML将告诉您模式匹配并非详尽无遗,也就是说,您有错过的模式,这意味着您在编译时而不是在运行时捕获错误。
这是你的功能版本。
fun sum [] = []
| sum [x] = [x]
| sum (x::y::xs) = x::sum (x+y::xs)
我将添加移动到递归调用,因为如果你添加第一个东西,那么结果的第一个元素将是原始列表的第一个两个元素加在一起。