Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return the index of a for loop in OCaml?

let find_free_next heap start = 
  for i = start to ((Array.length heap)-1) do
     match heap.(i) with 
     Hdr (Free (h), g)  ->
        i
  done

How can i return the index of a loop as an integer once the match has been found?

like image 736
Takkun Avatar asked Feb 27 '12 01:02

Takkun


People also ask

How do you break out of a loop in OCaml?

OCaml doesn't support the concept of breaking out of a for loop early i.e. it has no break , continue or last statements. (You could throw an exception and catch it outside, and this would run fast but often looks clumsy.)

Are there for loops in OCaml?

While Loop and For Loop Most OCaml programmers do a lot of their loops via recursive functions. However, there are two imperative loops: a conventional while loop, and a counting for loop like that of Algol 60.


2 Answers

If you want to stick to the imperative style, you can use an exception to exit the loop:


exception Found of int

let find_free_next heap start = 
  try
    for i = start to Array.length heap - 1 do
       match heap.(i) with 
       | Hdr (Free (h), g)  -> raise (Found i)
       | _ -> () (* If it is not what you are seeking *)
    done;
    raise Not_found   
  with
  | Found n -> n

But generally, as ppl have already written, functional style is more preferred in OCaml:


let find_free_next heap start =
  let len = Array.length heap in
  let rec find i =
    if i >= len then None
    else 
      match heap.(i) with
      | Hdr (Free h, g) -> Some i
      | _ -> find (i+1)
  in
  find start

In this example, there is not much difference between the two versions, but use of exceptions for exiting loops/recursions must be used with caution; you can introduce control flow bugs pretty easily with them, and they are sometimes hard to debug.

BTW, you can use Array.unsafe_get heap i to speed up your array access since you can be sure that i is always in the valid range of the array the above examples. (Oh, we need start >= 0 check in addition, though.)

like image 132
camlspotter Avatar answered Oct 22 '22 02:10

camlspotter


Asumu Takikawa is right, the for loop in OCaml doesn't return a result. In idiomatic OCaml, you should use recursion instead. Ideally there would be a standard function like List.find that works for arrays. There is a function BatArray.findi in OCaml Batteries Included that does what you seem to want.

like image 35
Jeffrey Scofield Avatar answered Oct 22 '22 02:10

Jeffrey Scofield