0

Pretty much what the title says. I just started learning SML and am having trouble with my first project. I understand this is a very basic question and it would be incredibly easy for me to do in something like java, but I'm having difficulty understanding SML. I need to write a function intsFromTo. It should take a pair of integers, low and high, and return a list of consecutive integers in ascending order, namely all those that are greater than or equal to low and less than or equal to high.

Here's what I have so far

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

and I'm getting the following errors which I'm also having difficulty understanding.

https://i.stack.imgur.com/hMRRR.png

Any and all help to get me going would be greatly appreciated.

Jonerhan
  • 97
  • 1
  • 11

3 Answers3

1

Several issues in your code, just reveal the hidden segments to see the answers, but I'm just giving hints first to help you work it out by yourself.

  1. what is the syntax for a function body?

Recall that a function body requires a let ... in ... end when defining local values, as you are doing there with intList:

  1. what is the value nill?

You probably meant nil, or []

  1. what are you trying to express with intList::low intsFromTo(low+1,high)?

You've got that part almost right: your goal is to return the list made of the current low element, followed by the list of element from its successor to the highest. This is written : low :: intsFromTo (low+1,high). The long explanation: you actually wrote 2 different expressions side by side (intList::low and the recursive call to intsFromTo), the first of which is not a function, so it cannot be applied to the second (remember that this is the same principle as in lambda calculus).

  1. And then?

    After these changes, the resulting program should compile, but its implementation could be improved (hint: intList?). This is left as an exercise for the reader.

Community
  • 1
  • 1
didierc
  • 14,572
  • 3
  • 32
  • 52
  • Sure it's probably homework. In my opinion, obfuscating a partial answer doesn't really make the internet better over the long term. That doesn't mean I don't appreciate the effort or sentiment behind the post, just that the approach is more appropriate for a discussion forum than a Question and Answer site striving to place clear concise correct information on the internet. – ben rudgers Mar 03 '15 at 15:19
  • I didn't really think about this matter, I found out about this feature (which is supported by stackoverflow markdown implementation btw, so why include it if it's not to use it?), and decided to use it then, it seemed a good idea. – didierc Mar 26 '15 at 19:07
1

Note: The code could be mode more compact for style but might not so clearly illustrate the basic concepts.

Typical Recursion

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

Alternative Approach

An alternative way to produce the list is using map-reduce style semantics on a list.

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 *)

Why an Alternative? Just out of curiosity.

Performance

Anecdotal timing indicates that the first version is about twice as fast as the second version using:

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

At least on my computer while it is being used for other things.

ben rudgers
  • 3,647
  • 2
  • 20
  • 32
-1

Late answer, but here's a lovely compact recursive definition of this.

fun intList a b = if (a = b) then [b]
                  else a::intList (a+1) b;
  • Will this work if `a > b`? Would you have spotted that if you had used `low` and `high` as in the question? – AdrianHHH Jan 25 '17 at 11:29