OCaml 这个变体表达式应该有类型 unit
OCaml This variant expression is expected to have type 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
我不知道这是什么意思。我测试了 if 语句在其他方法中返回 true/false 并且它工作得很好。我不知道为什么它在这种情况下不起作用,所以如果有人可以提供帮助,请帮忙。
“for 表达式”必须 return 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);;
一个更实用的解决方案是使用 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
这里的异常用于当我们发现一个女王瞄准该位置时立即返回。
其他答案已经解决了您的直接问题,但也有一些机会可以解决您的代码中不适合发表评论的问题。希望这些建议可以通过消除外来噪音,使您将来更容易对代码进行推理。
这听起来很迂腐,但请记住 OCaml 中没有条件 语句 。相反,它们是具有值的 expressions。我想你已经明白这一点了,但术语很重要。
此外,您使用条件语句的方式存在一些问题。如果您唯一要做的就是返回 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 发布的答案中看到(但未详细说明)。
我无法理解 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
我不知道这是什么意思。我测试了 if 语句在其他方法中返回 true/false 并且它工作得很好。我不知道为什么它在这种情况下不起作用,所以如果有人可以提供帮助,请帮忙。
“for 表达式”必须 return 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);;
一个更实用的解决方案是使用 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
这里的异常用于当我们发现一个女王瞄准该位置时立即返回。
其他答案已经解决了您的直接问题,但也有一些机会可以解决您的代码中不适合发表评论的问题。希望这些建议可以通过消除外来噪音,使您将来更容易对代码进行推理。
这听起来很迂腐,但请记住 OCaml 中没有条件 语句 。相反,它们是具有值的 expressions。我想你已经明白这一点了,但术语很重要。
此外,您使用条件语句的方式存在一些问题。如果您唯一要做的就是返回 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 发布的答案中看到(但未详细说明)。