1

The following method determines how many numbers can be added up starting from the beginning of the list without adding up to 4:

number_before_Reaching_sum (4, [1,2,3,4,6]);
should return : val it = 2 : int

fun number_before_reaching_sum (sum : int * int list) =
    let val len_orig_list = length (#2 sum)
    in fun num_bef_reach_sum (sum) =
           if #1 sum <= 0
           then len_orig_list - (length (#2 sum)) - 1
           else num_bef_reach_sum (#1 sum - hd (#2 sum), tl (#2 sum))
    end

syntax error: inserting LOCAL
syntax error found at EOF

I can't seem to find the errors in this code. I have some experience with Python, but just starting to learn sml. I'm loving it, but I don't understand all the error messages. I have really spent hours on this, but I think I don't know enough to solve my problem. I tried exchanging let with local, but i still got a syntax error (equalop). I think that the function between in and end is an expression and not a declaration. But I would appreciate any comments on this. If you come up with alternative code, it would be great if you did it without using more advanced features, since I'm just trying to get the basics down :-)

1 Answer 1

1

You probably meant this:

fun number_before_reaching_sum (sum : int * int list) =
    let 
        val len_orig_list = length (#2 sum)
        fun num_bef_reach_sum (sum) =
           if #1 sum <= 0
           then len_orig_list - (length (#2 sum)) - 1
           else num_bef_reach_sum (#1 sum - hd (#2 sum), tl (#2 sum))
    in 
        num_bef_reach_sum (sum)
    end

With let … in … end, the part between let and in is for the local definitions; the part between in and end is for the expression which will be the evaluation of the let … in … end expression (this construct is indeed an expression).

Think of let … in … end as a possibly complex expression. You hoist parts of the expression as definitions, then rewrite the complex expression using references to these definitions. This help write shorter expressions by folding some of its sub‑expressions. This construct is also required when recursion is needed (a recursion requires a defining name).

Another way to understand it, is as the application of an anonymous function whose arguments bindings are these definitions.

Ex.

let
   val x = 1
   val y = 2
in
   x + y
end

is the same as writing

(fn (x, y) => x + y) (1, 2)

which is the same as writing

1 + 2

You erroneously put a definition at the place of the expression the whole evaluates to.

(note I did not check the function's logic, as the question was about syntax)

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

1 Comment

Thank you. That cleared it up for me. Of course the function has to be defined first (between the let and in), and then the expression is only when you call the function between the in and end. Now I can proceed to test the logic of my function (as soon as I get home to my computer) :-). Thank you for taking the time, Hibou57.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.