【问题标题】:SML list summingSML 列表求和
【发布时间】:2013-01-14 10:11:24
【问题描述】:

我对 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】:

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

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

      - fun rec_ sum : int list -> int list = raise Domain;
      val rec_ = fn : 'a -> int list -> int list
      
    • 你应该小心使用 head 和 tail 函数,当你不对 列表中的元素数。这可以通过长度函数来完成,或者(甚至 更容易并且通常更好)通过模式匹配元素的数量。

    • 您的代码包含 sum 作为函数调用和 tail 作为变量。变量 tail 从来没有 已定义,并使用 sum 作为函数调用,让我相信您实际上是在使用 rec 作为关键字,但不知道是什么意思。

      在使用 val 关键字定义函数时,使用关键字 rec。在这种情况下,rec 是 需要能够定义递归函数(不足为奇)。实际上,关键字 fun 是 val rec 的语法糖(派生形式)。

    以下 3 个是如何制作它的示例:

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

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

    第二个示例使用了一个辅助函数,并添加了一个参数(累加器)。该列表以相反的顺序构造,以避免使用慢速附加 (@) 运算符。因此,我们在返回之前反转列表:

    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)
    

    【讨论】:

      【解决方案2】:

      试试这个 -

      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 关键字。

      【讨论】:

        猜你喜欢
        • 2022-07-09
        • 2011-12-22
        • 2016-01-01
        • 2020-08-22
        • 1970-01-01
        • 1970-01-01
        • 2015-11-08
        • 2014-12-18
        • 2011-05-26
        相关资源
        最近更新 更多