在OCaml中循环“中断”

时间:2016-12-03 16:27:42

标签: arrays for-loop ocaml break

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

我有这段代码:

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;;

但有人说: 错误:此表达式具有类型颜色数组        但是预期表达式为单位

如何返回符合条件的数组?

3 个答案:

答案 0 :(得分:4)

让我们用<big-for-loop>项代替你的big 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都必须返回相同类型的值。在您的情况下,<big-for-loop>表达式返回类型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

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

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

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

答案 1 :(得分:2)

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

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

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

  with Exit a -> a;;

答案 2 :(得分:2)

您的问题是try语句的正文都需要返回与with子句相同类型的值。但是,在您的示例中,正文具有类型单位和with子句类型colour array(或类似的东西)。

你要做的事情取决于到达循环的末尾是否会产生结果或错误。

如果它应该产生结果,你有两个选择。首先,您只需在最后; arraycolours之后添加done即可返回数组。其次,您可以在最后; raise Exit之后使用done

如果到达循环结束将是一个错误,你应该提出一个不同的例外,例如最终; failwith "this cannot happen"后的done