for loops should not return values, they only perform the operation a fixed number of times, and then return () (one). If you want to repeat and finally return something, you can:
have a link outside the loop in which you add the final result when you receive it, and then, after the loop returns the link content
use recursive function directly
use a higher order function that will encapsulate the workaround for you and allow you to focus on the application logic
A higher function is good if your data structure supports it. However, simple traversal functions such as fold_left do not support prematurely terminating the iteration. If you want to support this (and obviously it will be interesting in your use case), you should use a workaround with premature exit support. For simple functions like yours, a simple recursive function is probably the simplest.
In F # it should also be possible to write your function in an imperative style, using yield to turn it into a generator, and then finally make the generator get the result. This can be seen as an analogue of the OCaml method of using exceptions to jump out of a loop.
Edit: A good solution to avoid “premature stopping” issues is to use a lazy intermediate data structure that will only be created for the first satisfactory result. This is an elegant and good scripting style, but still less effective than direct exit support or simple recursion. I think it depends on your needs; Is this feature used for the critical path?
Edit:. The following is sample code. They are OCaml, and the data structures are different (some of them use libraries from Batteries ), but the ideas are the same.
(* using a reference as accumulator *) let most_significant_bit input_bits = let result = ref None in for i = Array.length input_bits - 1 downto 0 do if input_bits.(i) then if !result = None then result := Some i done; !result let most_significant_bit input_bits = let result = ref None in for i = 0 to Array.length input_bits - 1 do if input_bits.(i) then (* only the last one will be kept *) result := Some i done; !result (* simple recursive version *) let most_significant_bit input_bits = let rec loop = function | -1 -> None | i -> if input_bits.(i) then Some i else loop (i - 1) in loop (Array.length input_bits - 1) (* higher-order traversal *) open Batteries_uni let most_significant_bit input_bits = Array.fold_lefti (fun result i -> if input_bits.(i) && result = None then Some i else result) None input_bits (* traversal using an intermediate lazy data structure (a --- b) is the decreasing enumeration of integers in [b; a] *) open Batteries_uni let most_significant_bit input_bits = (Array.length input_bits - 1) --- 0 |> Enum.Exceptionless.find (fun i -> input_bits.(i)) (* using an exception to break out of the loop; if I understand correctly, exceptions are rather discouraged in F
source share