2

I'm trying to write a function that accepts an int n and returns a list that runs down from n to 0.

This is what I have

let rec downFrom n =
let m = n+1 in
if m = 0 then                                                                                  
  []                                                                                           
else                                                                                            
  (m-1) :: downFrom (m - 1);;

The function compiles ok but when I test it with any int it gives me the error Stack overflow during evaluation (looping recursion?).

I know it's the local varible that gets in the way but I don't know another way to declare it. Thank you!!!

3 Answers 3

3

First, the real thing wrong with your program is that you have an infinite loop. Why, because your inductive base case is 0, but you always stay at n! This is because you recurse on m - 1 which is really n + 1 - 1

I'm surprised as to why this compiles, because it doesn't include the rec keyword, which is necessary on recursive functions. To avoid stack overflows in OCaml, you generally switch to a tail recursive style, such as follows:

let downFrom n =
  let rec h n acc = 
    if n = 0 then List.rev acc else h (n-1) (n::acc)
  in
  h n []

Someone suggested the following edit:

let downFrom n =
    let rec h m acc =
        if m > n then acc else h (m + 1) (m::acc)
    in
    h 0 [];

This saves a call to List.rev, I agree.

Sign up to request clarification or add additional context in comments.

3 Comments

thank you! although i havent learn tail recursion, i changed the last statement to (m-1) :: downFrom (m - 2) and it worked
as a hint, I would (for better style) simply eliminate the definition of m, and instead replace it by n+1 everywhere, otherwise it looks awkward.
I have corrected a few typos to have your version of downFrom compile. But still, it returns an increasing list, while the OP asks for a decreasing list.
1

The key with recursion is that the recursive call has to be a smaller version of the problem. Your recursive call doesn't create a smaller version of the problem. It just repeats the same problem.

Comments

0

You can try with a filtering parameter syntax:

let f = function
   p1 -> expr1
 | p2 -> expr2
 | p3 -> ...;;

let rec n_to_one =function
  0->[]
  |n->n::n_to_one (n-1);;

# n_to_one 3;;
- : int list = [3; 2; 1]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.