Rohit88
Rohit88

Reputation: 13

Syntax errors in sml: Inserting LOCAL

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

Upvotes: 1

Views: 1577

Answers (1)

Hibou57
Hibou57

Reputation: 7190

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)

Upvotes: 1

Related Questions