"Break" OCaml 中的 for 循环

"Break" for loop in OCaml

我需要在 OCaml 的 5 元素数组中测试所有可能的组合,如果任何组合满足条件,我必须停止循环和 return 该数组,但这并不容易 return为了...

我有这个代码:

let myfunction t =
 let arraycolours = Array.make 5 W in
  try
   for i=0 to 3 do
    Array.set arraycolours 0 (inttocolour i);
    for j=0 to 3 do
     Array.set arraycolours 1 (inttocolour j);
     for k=0 to 3 do
      Array.set arraycolours 2 (inttocolour k);
      for l=0 to 3 do
       Array.set arraycolours 3 (inttocolour l);
       for m=0 to 3 do
        Array.set arraycolours 4 (inttocolour m);
        if test arraycolours = t then raise Exit
       done
      done
     done
    done
   done
  with Exit -> arraycolours;;

但是那里说: 错误:此表达式的类型为颜色数组 但表达式应为 unit

类型

如何return得到满足条件的数组?

您应该定义一个新的异常类型:

exception ExitArray of <type of arraycolor> (* may be "int array" in your case *) 

然后,当你想退出循环时:你抛出一个异常 raise ExitArray arraycolors ,最后你捕获异常并收集结果:

  with Exit a -> a;;

你的问题是 try 语句的主体都需要 return 一个与 with 子句相同类型的值。但是,在您的示例中,正文具有类型 unit 和 with 子句类型 colour array (或类似的东西)。

您必须做什么取决于到达循环末尾是应该产生结果还是产生错误。

如果它应该产生结果,您有两种选择。首先,您可以简单地在最后一个 done 之后添加 ; arraycolours 到 return 数组。其次,您可以在最后一个 done.

之后使用 ; raise Exit

如果到达循环末尾是一个错误,您应该引发一个不同的异常,例如; failwith "this cannot happen"后最后done.

让我们通过用 <big-for-loop> 项替换你的大 for 循环来折叠你的复杂函数定义。

let myfunction t =
 let arraycolours = Array.make 5 W in
  try
    <big-for-loop>
  with Exit -> arraycolours

<big-for-loop> 实际上是一个表达式,其值 () 具有类型单位。 try/with 表达式具有以下语法:

  try e1 with exn -> e2

e1e2 必须是同一类型的 return 值。在你的例子中,<big-for-loop> 表达式 return 是一个 unit 类型的值,而 with 子句下的表达式具有 colour array 类型。这基本上意味着,根据您是否能够找到组合,您的函数将有不同的类型。但是 OCaml 中的类型不能依赖于运行时值,所以我们有一个类型错误。

有不同的解决方案,具体取决于您尝试实施的内容,例如,如果未找到组合,您可以引发 Not_found 异常,例如,

let myfunction t =
 let arraycolours = Array.make 5 W in
  try
    <big-for-loop>;
    raise Not_found
  with Exit -> arraycolours

或者,您可以将结果包装到选项类型中,如果找到组合则 return Some array,否则 None

let myfunction t =
 let arraycolours = Array.make 5 W in
  try
    <big-for-loop>;
    None
  with Exit -> Some arraycolours

我个人更喜欢后一种解决方案。