如何解决OCaml 此变体表达式应具有类型 unit
我无法弄清楚 if 语句的问题。
我的代码:
type chess_board = char array array;;
type position = int * int;;
let chess_board_1:chess_board = [|
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';'Q';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
|];;
let queen_targeting (chess:chess_board) pos =
match pos with
|(x0,y0) ->
for y = 0 to Array.length chess -1 do
for x = 0 to Array.length chess.(y) -1 do
if chess.(y).(x) = 'Q'
then
if (
x = x0 || (* Check horizontaly *)
y = y0 || (* Check verticaly *)
x - x0 = y - y0 (* Check diagonaly *)
)
then true
else false
done
done
;;
queen_targeting chess_board_1 (3,3);; (* Expected true *)
我收到此错误消息:
File "[32]",line 27,characters 25-29:
Error: This variant expression is expected to have type unit
The constructor true does not belong to type unit
Characters 874-878:
then true
我不知道这是什么意思。我测试了是否在其他方法中返回 true/false 的语句,它工作得很好。我不知道为什么它在这种情况下不起作用,所以如果有人可以帮忙,请帮忙。
解决方法
更实用的解决方案是使用 Array.iteri
:
let queen_targeting (chess:chess_board) (x0,y0) =
let exception Return of bool in
let threat y x case =
if case = 'Q' && (x = x0 || y = y0 || x - x0 = y - y0) then
raise (Return true)
in
match Array.iteri (fun y -> Array.iteri (threat y)) chess with
| () -> false
| exception Return b -> b
这里的异常用于在我们找到定位该位置的皇后后立即返回。
,“for 表达式”必须返回 unit
,因此不会传播结果。例如:
# let x = for y = 0 to 10 do true done;;
潜在客户发出此警告:
Warning 10: this expression should have type unit.
val x : unit = ()
解决方案是使用可变引用:
type chess_board = char array array;;
type position = int * int;;
let chess_board_1:chess_board = [|
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
[|' ';' ';' ';' ';' ';' ';'Q';' '|];
[|' ';' ';' ';' ';' ';' ';' ';' '|];
|];;
let queen_targeting (chess:chess_board) pos =
match pos with
|(x0,y0) ->
let result = ref false in
for y = 0 to Array.length chess -1 do
for x = 0 to Array.length chess.(y) -1 do
if chess.(y).(x) = 'Q'
then
if (
x = x0 || (* Check horizontaly *)
y = y0 || (* Check verticaly *)
x - x0 = y - y0 (* Check diagonaly *)
)
then result := true
else result := false
done
done;
false || !result
;;
queen_targeting chess_board_1 (3,3);;
,
其他答案已经解决了您的直接问题,但有一些机会可以解决您的代码中不太适合评论的问题。希望这些建议可以消除多余的噪音,从而使您将来更容易推理您的代码。
这听起来很迂腐,但请记住,OCaml 中没有条件语句。相反,它们是具有值的表达式。我怀疑您已经了解这一点,但术语很重要。
此外,您使用条件的方式也存在一些问题。如果您唯一要做的就是返回 true 或 false,那么只需直接使用布尔表达式。考虑一个简单的例子。
if a < b && b < c then true else false
这与:
a < b && b < c
第三,当您有嵌套条件时,这些通常可以简化。我将稍微修改您的代码并暂时删除注释。
if chess.(y).(x) = 'Q' then
if x = x0 || y = y0 || x - x0 = y - y0 then
true
else
false
我们知道我们可以将其简化为:
if chess.(y).(x) = 'Q' then
x = x0 || y = y0 || x - x0 = y - y0
但我们只会在第一个条件检查出来时检查 ||
ed 条件,所以我们可以将整个事情重写为:
chess.(y).(x) = 'Q' && (x = x0 || y = y0 || x - x0 = y - y0)
这可以在@octachron 发布的答案中看到(但没有详细说明)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。