views:

356

answers:

1

I am having issues manipulating deeply nested lists in OCaml in the below context.

class foo (pIn:int)=
object (self)
    val p = pIn
    val even = if (pIn mod 2) = 0 then true else (false)
    method doIt = "doIt"
    method isEven = even
    method getP = p
end;;

let rec createListOfElements howMany =  (
    Random.self_init ();
    if howMany > 1 then ((new foo (Random.int 10))::(createListOfElements (howMany - 1)))
    else ([(new foo (Random.int 10))]) );;

let myList = createListOfElements 5;;

let rec process1 param =
     if param <= 10 then
       let f = new foo param in    (
       if f#isEven then (myList <- List.append myList (createListOfElements f#getP));
       Printf.printf "%s\n" f#doIt;
       process1 (param+1)         )
in process1 0;;

The error I get is, "Unbound instance variable myList". How do I go about assigning the result of "List.append myList (createListOfElements f#getP) to myList in this context?

Thanks!


Edited function:

let myList = ref (createListOfElements 5);;

let rec process1 param =
     if param <= 10 then
       let f = new foo param in    (
       if f#isEven then (myList <- !myList @ (createListOfElements f#getP));
       Printf.printf "%s\n" f#doIt;
       process1 (param+1)         )
in process1 0;;
A: 

You have to use references to break persistence --since functional programming uses persistent data. Use the ref keyword in the declaration of myList:

let myList = ref (createListOfElements 5)

To dereference the list use !, so the line in question becomes

if f#isEven then
  myList := !myList @ f#getP;

I suggest you use an accumulator as it's in the spirit of the functional-programming style, like this:

let rec process1 lst = function
  | x when x <= 10 ->
      let f = new foo x in
      if f#isEven then
          process1 (lst @ (createListOfElements f#getP)) (param+1)
      else
          process1 lst (param+1)
  | _ -> lst

EDIT:

I didn't compile my code and didn't notice that you are using the wrong symbol to change the value of the reference. The correct symbol is, :=. See my change above. I strongly suggest you avoid references, though, and go the accumulator route.

nlucaroni
I edited the original post. Compiling this returns the same error. The second code box in your comment was missing the call to createListOfElements (the real function does more than that but for simplicity I used this name/implemention) but I don't believe that should matter. What am I doing wrong?
Mat