"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
e1
和 e2
必须是同一类型的 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
我个人更喜欢后一种解决方案。
我需要在 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
e1
和 e2
必须是同一类型的 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
我个人更喜欢后一种解决方案。