刚刚开始学习SML:如何获取两个整数并返回之间的所有整数列表

时间:2015-02-27 02:31:52

标签: sml smlnj ml

相当于标题所说的内容。我刚刚开始学习SML并且遇到了第一个项目的问题。我知道这是一个非常基本的问题,对于像java这样的东西我会非常容易,但是我很难理解SML。我需要编写一个函数intsFromTo。它应该采用一对整数,低和高,并按升序返回连续整数列表,即所有大于或等于低和小于或等于高的整数。

这是我到目前为止所拥有的

fun intsFromTo (low,high) = val intList = []
if low >= high then nill
else intList::low intsFromTo(low+1,high);

我发现以下错误,我也很难理解。

http://i.imgur.com/QZ0WT6j.png

非常感谢任何帮助我前进的帮助。

3 个答案:

答案 0 :(得分:1)

您的代码中存在几个问题,只是显示隐藏的细分以查看答案,但我只是先给出提示,以帮助您自己解决问题。

  1. 函数体的语法是什么?
  2.   

    回想一下,在定义本地值时,函数体需要let ... in ... end,就像你在intList那样做:

    1. 价值nill是什么?
    2.   

      您可能需要nil[]

      1. 您想用intList::low intsFromTo(low+1,high)表达什么?
      2.   

        你的部分几乎是正确的:你的目标是返回由当前low元素组成的列表,然后是从其后继者到最高元素的元素列表。这写成:low :: intsFromTo (low+1,high)。很长的解释:你实际上并排写了两个不同的表达式(intList::low和递归调用intsFromTo),第一个不是函数,所以它不能应用于第二个(记住这与lambda演算中的原理相同。

        1. 然后呢?

          在这些更改之后,生成的程序应该编译,但是它的实现可以改进(提示:intList?)。这留给读者练习。

答案 1 :(得分:1)

注意:代码可能是风格更紧凑的模式,但可能无法清楚地说明基本概念。

典型递归

fun intsFromTo(low, high) =
  let
      val out = []
  in
      if 
          low <= high
      then
          low :: intsFromTo2(low + 1, high)
      else
          out
  end

替代方法

生成列表的另一种方法是在列表中使用map-reduce样式语义。

fun intsFromTo(low, high) =
  if high > low         
  then     (* the list will contain at least one value *)
     if
       high >= 0
     then
       List.tabulate((high + 1) - low,
                fn k => k + low)
     else
       List.rev(
          List.tabulate((~low + 1) + high,
                fn k => ~k + high))
  else
      []    (* list empty: low >= high *)

为何选择? 只是出于好奇。

效果

轶事时间表明第一个版本的速度是第二个版本的两倍:

fun time() =
  let 
      val t = Timer.startCPUTimer();
  in
      intsFromTo(~1000000,1000000);
      Time.toReal(#usr(Timer.checkCPUTimer(t)))
  end

至少在我的电脑上用于其他事情。

答案 2 :(得分:-1)

迟到的答案,但这是一个可爱的紧凑递归定义。

fun intList a b = if (a = b) then [b]
                  else a::intList (a+1) b;