SML - 使用原始列表的元素构建新列表 - 错误:运算符和操作数不一致[literal]

JAN*_*JAN 0 sml smlnj

给定一个数字列表,我想创建一个新列表,其中index处的元素ii-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);是问题的原因,但我该如何解决呢?

问候

Tay*_*can 5

看看你的基本情况.您希望函数返回一个列表,因此基本案例应返回列表.

fun sum []      = []
  | sum [x]     = [x]
  | sum (x::xs) = ...
Run Code Online (Sandbox Code Playgroud)

我更换nil[]因为我更喜欢它 - 它并不重要.

另一件事 - 永远不要使用hdtl运算符(有例外,但现在,只是不要).当然,在你的功能中,它不会成为一个问题,因为你照顾的情况,但还有另一个原因.如果你这样做:

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)

我将添加移动到递归调用,因为如果你添加第一个东西,那么结果的第一个元素将是原始列表的前两个元素一起添加.