0
votes

I am trying to make function restric that would restrict a table's values according to columns that have value [value]. My idea is to make a list consisting of trues and falses for the column that satisfy condition column and value parameters. Later on recursive match would chose the columns and a listmaker function would make a new column according to true falses list.

When it comes to storing in ocaml nested variables, let...in scoping I am very confused. What is wrong with the code bellow?

let rec restrict (column, value, aTable) = match aTable with
    name,[]->[]
  |name,(col,vals)::rest->if col=column
      then (col,auxListMaker(vals,trueFalseList))::restrict (column,value.(name,rest))
      else restrict (column,value.(name,rest))

let rec auxTrueFalser (column, value, aTable) = match aTable with 
    name,[]->[]
  |name,(col,vals)::rest-> if column=col 
      then (if List.hd vals = value 
            then true::aux1(column,value,(name,[(col,List.tl vals)]))
            else false::aux1(column,value,(name,[(col,List.tl vals)])))
      else aux1(column,value,(name,rest)) 
in 

let trueFalseList =  auxTrueFalser (column, value, aTable) in

let rec auxListMaker (vals, trueFalseList) = match vals with
    []->[]
  |h::t -> if List.hd trueFalseList
      then h::auxListMaker(t,List.tl trueFalseList)
      else auxListMaker(t,List.tl trueFalseList)
in
1

1 Answers

3
votes

The main thing to realize is that there are two uses of let. The first form is used to define the values in a module, and must appear at the outermost level of a module. It looks like this:

let name = expression

As a handy syntax, you can define a function at the outermost level like this:

let name arg = expression

The other form of let can appear anywhere, and is used to define a local variable. It looks like this:

let name = expression1 in expression2

This establishes name as a local variable with the value given by expression1. The scope of the name (where it can be used) is expression2.

Again, as a handy syntax, you can define a local function like this:

let name arg = expression1 in expression2

It looks to me like auxListMaker and auxTrueFlser are supposed to be local functions defined inside restrict. And trueFalseList is supposed to be a local (non-function) value. So the form of restrict would be something like this:

let rec restrict (column, value, aTable) =

    let auxTrueFalser (column, value, aTable) =
        ...
    in

    let auListMaker (vals, trueFalseList) =
        ...
    in

    let trueFalseList = auxTrueFalser (column, value, aTable) in

    ... (* body of restrict *)

In this layout restrict is defined at the top level (so just with let, no in). The other names are local variables (values and functions), and so are defined with let ... in.

Also note that you must define a name before using it. In your code the name auxListMaker is used before being defined. In the above layout, the order is OK.

Update

Answers to further questions.

The scope of the first form of let (with no in) is the rest of the module. For the common case of a simple .ml source file, this means the rest of the file.

Yes, the restrict function shown in the above schematic layout will re-evaluate the value for trueFaleList at every recursive call.

If you're working at a terminal that OCaml knows about, it underlines the place where it thinks you have a syntax error. The syntax of the first few lines of the schematic layout above is clearly OK. You'll have to show your code (or the smallest self-contained subset that shows the problem) and the specific error message you got.