Functional programming 如何在OCaml中返回for循环的索引?

Functional programming 如何在OCaml中返回for循环的索引?,functional-programming,ocaml,Functional Programming,Ocaml,找到匹配项后,如何将循环的索引作为整数返回?Ocaml中的循环被认为是必需的,因此它不应该返回结果(单位除外)。因此,如果您试图返回非单元结果,编译器将发出警告 Ocaml不允许您从循环返回结果的原因是,这不是一个非常实用的习惯用法。如果使用递归函数而不是循环,则很容易提前退出并返回结果(通过返回结果而不是重复)。如果您想编写惯用的Ocaml,可能需要在本例中使用递归。Asumu Takikawa是正确的,Ocaml中的for循环不会返回结果。在惯用的OCaml中,应该使用递归。理想情况下,应该

找到匹配项后,如何将循环的索引作为整数返回?

Ocaml中的循环被认为是必需的,因此它不应该返回结果(单位除外)。因此,如果您试图返回非单元结果,编译器将发出警告


Ocaml不允许您从循环返回结果的原因是,这不是一个非常实用的习惯用法。如果使用递归函数而不是循环,则很容易提前退出并返回结果(通过返回结果而不是重复)。如果您想编写惯用的Ocaml,可能需要在本例中使用递归。

Asumu Takikawa是正确的,Ocaml中的
for
循环不会返回结果。在惯用的OCaml中,应该使用递归。理想情况下,应该有一个标准函数,如
List.find
,它适用于数组。其中有一个函数可以执行您想要的操作。

如果您想坚持命令式样式,可以使用异常退出循环:



但一般来说,正如ppl所写,功能性风格在OCaml中更受欢迎:



在本例中,这两个版本之间没有太大区别,但必须小心使用异常退出循环/递归;您可以很容易地使用它们引入控制流bug,而且它们有时很难调试


顺便说一句,您可以使用Array.unsafe\u get heap i来加速数组访问,因为您可以确保i始终在上面示例中的数组有效范围内。(哦,我们还需要开始>=0检查。)

更简单、更高效(根本没有分配):

或者,用命令式:

let rec find_free_next heap start =
  if start = Array.length heap then raise Not_found;
  match heap.(i) with
  | Hdr (Free h, g) -> i
  | _ -> find_free_start heap (i+1)
(请注意,
raise exit
并不仅仅因为预计算了异常而进行分配)。

通过“异常是预计算的”,您的意思是在循环之前添加
let exit=exit
,可以防止一些低效率吗?对于最近的OCaml编译器,这种情况还会发生吗?
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
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
let rec find_free_next heap start =
  if start = Array.length heap then raise Not_found;
  match heap.(i) with
  | Hdr (Free h, g) -> i
  | _ -> find_free_start heap (i+1)
let exit = Exit
let find_free_next heap start =
  let pos = ref (-1) in
  try
    for i = start to Array.length heap - 1 do
      match heap.(i) with
      | Hdr (Free h, g) -> pos := i; raise exit
      | _ -> ()
    done;
    raise Not_found
  with Exit -> !pos