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

时间:2013-02-17 16:29:50

标签: sml smlnj

给定一个数字列表,我想创建一个新列表,其中索引为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);的递归规则是其中的原因 问题,但我该如何解决?

此致

1 个答案:

答案 0 :(得分:5)

查看您的基本案例。您希望函数返回一个列表,因此基本案例应返回列表。

fun sum []      = []
  | sum [x]     = [x]
  | sum (x::xs) = ...

我将nil替换为[],因为我更喜欢它 - 这并不重要。

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

fun foo [] = ...
  | foo (x::y::xs) = ...

SML将告诉您模式匹配并非详尽无遗,也就是说,您有错过的模式,这意味着您在编译时而不是在运行时捕获错误。

这是你的功能版本。

fun sum [] = []
  | sum [x] = [x]
  | sum (x::y::xs) = x::sum (x+y::xs)

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