ana M
ana M

Reputation: 3

Code not working: sorting array in ocaml

I am new to Ocaml and I have a problem with this code (below). I am trying to write a program to sort array. I divided array into two halfs, and then I used Array.sort on those two arrays ( I am gonna fix that later, so i wont use Array.sort). And then I wanted to compare elements from those two arrays, but my code is not working. Can anybody tell me where is the problem?

let a =[|5;4;2;6;1;3|] ;;
let n = Array.length a;;


let l= Array.sub a 0 (n/2);;
Array.sort compare l;;
l;;
let ll= Array.length l;;


let r= Array.sub a (n/2) (n/2);;
Array.sort compare r;;
r;;
let lr=Array.length r;;

let merge l r a =
    let k =ref 0 in 
    let i = ref 0 in
    let j =ref 0 in

while( !i<ll && !j< lr) do
        if(l.(!i) <= r.(!j)) then
                a.(!k) <- l.(!i)
                i:= !i+1
        else begin
                a.(!k) <- r.(!j)
                j:= !j+1;
                k:= !k+1
        end;

while (!i<ll) do
        a.(!k)<-l.(!i)
        i:= !i+1;
        k:=!k+1;
done;

while (!j<ll) do
        a.(!k) <-r.(!j)
        j:= !j+1;
        k:= !k+1
done;
done;;

merge l r a;;

Upvotes: 0

Views: 504

Answers (2)

Lhooq
Lhooq

Reputation: 4441

Your problem comes from your misunderstanding of what instructions are. Let's try to explain it in a easy and short way :

  • If your expression returns a value, it's an expression (a bool, an int, a function ...)
  • If it doesn't return a value (which means it does a side effect), it's an instruction (and we say it returns unit because actually, that's what it does).

When you have a sequence (this is how multiple instructions executing one after another are called), you separate them with a ;.

So, for example, if I write this

let f x = x := 1; print_int !x; print_newline ()

I have a sequence and I have to separate my instructions with ;.

If I wrote :

let f x = x := 1 print_int !x print_newline ()

You can easily understand that OCaml can't know where the instructions are separated (is it x := 1 print_int; !x? Or anything else?) That's why you need ;.

Now comes the problem with if.

If you write

 if cond then instr1; instr2

What is parsed is

 (if cond then instr1); instr2

Yes, if cond then instr1 is an instruction because, well, it returns unit, no? So instr2 is not in your then block.

But if you write

 if cond then let e1 = e2 in instr1; instr2

Then instr2 is in the then block because the construction let ... in creates a block under which all instructions are nested.

If you're starting with OCaml, my precious advice would be this : always writebegin ... end in your conditionnals. You'll be assured that what you write is what you think is parsed.

Upvotes: 1

Uncle Pa
Uncle Pa

Reputation: 13

I'm too new to comment but will point out that every block needs either parentheses () or begin ... end. Thus, your very first if statement should have then begin at the end of the line. The statements between the begin and else need semi-colons to separate them as in:

if(l.(!i) <= r.(!j)) then begin
    a.(!k) <- l.(!i);
    i:= !i+1
end else begin
    a.(!k) <- r.(!j);
    j := !j+1;
    k:= !k+1
end;

The first two lines of the while loops also need semi-colons because they are also a block of statements. Note that you do not need a semi-colon for the last statement in a block. They are separators, not end-of-statement. Also, as a shortcut, you can use incr i for i := !i + 1 and similar statements. Also, never use l or ll as variable names. :-)

Upvotes: 1

Related Questions