0

我是另一个尝试使用 SML 元素完成 MOOC 课程的初学者。我想生成一个带有列表的函数,并生成第二个列表,其中元素相加。

如果正确完成,此函数将转换 before_reaching_sum_test([1,2,3,4,5,6,7,8,9]);为以下列表 [1,3,6,10,16,23,31,40]

这是我到目前为止所拥有的,但我很确定我做错了。

fun before_reaching_sum_test(ints: int list) =
if null (tl ints)    
then []
else (hd ints + hd (before_reaching_sum_test(tl ints)))::(before_reaching_sum_test(tl ints))

我知道这将省略初始列表的最后一个元素。但是这样的事情会起作用吗?

4

1 回答 1

2

您的问题在于这一行hd (before_reaching_sum_test(tl ints)),它一直在列表的尾部递归调用,直到它返回空列表,然后您尝试获取该列表的头部。因此引发了空异常。

它实际上可以非常简单地创建

fun before_reaching_sum_test (x::y::xs) = x :: before_reaching_sum_test(x+y::xs)
  | before_reaching_sum_test x = x

通过“将前一个数字向前推”并计算运行总和。

更新

为冲击做好准备

fun before_reaching_sum_test xs =
    if null xs then xs (* empty list *)
    else if null (tl xs) then xs (* one element list *)
    else (* Two or more elements in the list *)
      let
        val x = hd xs
        val y = hd (tl xs)
      in
        x :: before_reaching_sum_test (x+y :: tl (tl xs))
      end

这实际上是一个很好的例子,说明为什么模式匹配是一件好事。

于 2013-02-10T02:18:43.020 回答