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