Reputation: 3
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
Reputation: 4441
Your problem comes from your misunderstanding of what instructions are. Let's try to explain it in a easy and short way :
bool
, an int
, a function
...)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
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