Как заметил glennsl , отступ вашего кода не соответствует фактическому потоку управления. Я думаю, что отступ отражает то, что должен делать код, но я не проверял его.
Проблема в области действия match
: у нее более низкий приоритет, чем у точек с запятой, поэтому с кодом наподобие этого:
match x with
| false -> print_endline "false"
| true -> print_endline "in match"; print_endline "still in match";
print_endline "still in match despite the indentation"
сообщение «все еще в совпадении, несмотря на отступ» печатается только в случае true
. Вам нужно поставить круглые скобки или begin
/ end
вокруг соответствия (или поместить его в функцию, или присвоить результат с помощью let
, или как угодно, чтобы получить правильный синтаксис).
let subtract_arrays ~array1 ~array2 =
let length = Array.length array1 in
let newArray = Array.make length 0 in
let carry = ref false in
Core.Array.rev_inplace array1;
Core.Array.rev_inplace array2;
for i = 0 to length - 1 do
print_endline ("I is: " ^ (string_of_int i));
let result = ref 0 in
let bool1 = array1.(i) = 0 && array2.(i) = 0 in
let bool2 = array1.(i) = 0 || ( array1.(i) < array2.(i) ) in
print_endline "Before";
<strong>begin</strong> match ( bool1, bool2 ) with
| ( true, _ ) ->
(match !carry with
| true -> result := 1; carry := false;
| false -> result := 0);
| ( _, true ) ->
result := array1.(i) + 10 - array2.(i);
(match array1.(i + 1) with
| 0 -> array1.(i + 1) <- 9;
| _ -> array1.(i + 1) <- array1.(i + 1) - 1)
| ( _ , _ ) ->
result := array1.(i) - array2.(i) - (if !carry then 1 else 0);
carry := false;
<strong>end;</strong>
print_endline "After";
print_endline ("-- Middle Result is : " ^ (string_of_int !result));
<strong>begin</strong> match 0 > !result with
| true -> newArray.(i) <- -1 * !result; carry := true; print_endline ("True Result is : " ^ (string_of_int !result));
| false -> newArray.(i) <- !result; print_endline ("False Result is : " ^ (string_of_int !result));
<strong>end;</strong>
print_endline ("Ending I is: " ^ (string_of_int i));
done;
Core.Array.rev_inplace newArray;
newArray
;;
Использование match
для логических значений немного странно. Код будет легче понять с помощью if
. Обратите внимание, что в отличие от match
, if
связывается более плотно, чем точки с запятой.
Другой способ, с помощью которого ваш код трудно читать, - это использование изменяемых переменных там, где они не нужны. Это усложняет отслеживание того, как вычисляются значения. Создание carry
ссылки оправдано, поскольку значение должно переноситься на следующую итерацию цикла (хотя может быть более читабельно использовать рекурсивную функцию вместо цикла). Но result
не имеет смысла быть справочным: вы назначаете его только один раз.
let subtract_arrays ~array1 ~array2 =
let length = Array.length array1 in
let newArray = Array.make length 0 in
let carry = ref false in
Core.Array.rev_inplace array1;
Core.Array.rev_inplace array2;
for i = 0 to length - 1 do
let result =
if array1.(i) = 0 && array2.(i) = 0 then
let result = if !carry then 1 else 0 in
carry := false;
result
else if array1.(i) = 0 || array1.(i) < array2.(i) then
let result = array1.(i) + 10 - array2.(i) in
array1.(i + 1) <- begin match array1.(i + 1) with
| 0 -> array1.(i + 1) <- 9
| _ -> array1.(i + 1) - 1
end;
result
else
let result = array1.(i) - array2.(i) - (if !carry then 1 else 0) in
carry := false;
result
in
newArray.(i) <- (if 0 > result then (carry := true; -result) else result)
done;
Core.Array.rev_inplace newArray;
newArray
;;