我需要测试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;;
但有人说: 错误:此表达式具有类型颜色数组 但是预期表达式为单位
如何返回符合条件的数组?
答案 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
e1
和e2
都必须返回相同类型的值。在您的情况下,<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
。