Sml 列表求和

Sml 列表求和,sml,Sml,我是SML的新手,我正在尝试列表练习。目标是汇总列表中以前的数字并创建一个新列表。例如,输入列表[1,4,6,9]将返回[1,5,11,20] 到目前为止,这是我的解决方案,但我认为问题在于如何定义函数 fun rec sum:int list -> int list = if tl(list) = nil then hd(list) else hd :: sum((hd(tail) + hd(tl(list)))::tl(tl(list)))

我是SML的新手,我正在尝试列表练习。目标是汇总列表中以前的数字并创建一个新列表。例如,输入列表
[1,4,6,9]
将返回
[1,5,11,20]

到目前为止,这是我的解决方案,但我认为问题在于如何定义函数

fun rec sum:int list -> int list = 
    if tl(list) = nil then 
      hd(list)
    else 
      hd :: sum((hd(tail) + hd(tl(list)))::tl(tl(list)));
试试这个-

fun recList ([], index, sum) = []
  | recList (li, index, sum) =
    if index=0 then
        hd li :: recList (tl li, index+1, hd li)
    else
      sum + hd li :: recList (tl li, index+1, sum + hd li)

fun recSum li = recList (li, 0, 0)
就你而言-

recSum([1,4,6,9]) ;
将给予

val it = [1,5,11,20] : int list 

也不要使用
rec
作为有趣的名称-it关键字

除了使用rec作为函数名之外,还有一些小问题需要解决

  • 所做的显式类型注释将被视为函数结果的注释。 因此,根据您编写的内容,它应该返回一个函数,而不是预期的结果 列表从以下示例可以清楚地看出这一点:

    - fun rec_ sum : int list -> int list = raise Domain;
    val rec_ = fn : 'a -> int list -> int list
    
  • 当您不在屏幕上进行任何检查时,您应该小心使用head和tail功能 列表中的元素数。这可以通过length函数或(甚至)函数实现 通过模式匹配元素的数量,更容易(通常更好)

  • 您的代码包含sum作为函数调用,tail作为变量。可变尾部从未出现过 已经定义,并且使用sum作为函数调用,这让我相信您实际上在使用rec 作为一个关键词,但不知道它的意思

    使用val关键字定义函数时,使用关键字rec。在这种情况下,rec是 需要能够定义递归函数(这并不奇怪)。事实上,这个关键词很有趣 是val rec的语法糖(派生形式)

以下3个示例说明了如何制作:

第一个是简单、直接的解决方案

fun sumList1 (x::y::xs) = x :: sumList1 (x+y::xs)
  | sumList1 xs = xs
第二个示例使用了一个helper函数,并添加了一个参数(累加器)。该列表按相反顺序构造,以避免使用慢速附加(@)运算符。因此,我们在返回列表之前将其反转:

fun sumList2 xs =
    let
      fun sumList' [] acc  = rev acc
        | sumList' [x] acc = rev (x::acc)
        | sumList' (x :: y :: xs) acc = sumList' (y+x :: xs) (x :: acc)
    in
      sumList' xs []
    end
最后一个示例显示,如果使用标准列表函数,它可以多么小和容易。这里使用的是左折,以穿过所有元素。再次注意,列表是以相反的顺序构造的,因此它作为最后一步被颠倒:

fun sumList3 []      = []
  | sumList3 (x::xs) = rev (foldl (fn (a, b) => hd b + a :: b) [x] xs)