Существует несколько проблем с вашим кодом, поэтому давайте рассмотрим его.
let stevec = ref 0;
let n = ref 1;
Вы не должны написать такой код, как и ;
является выражением сепаратором (и вы используете его здесь в качестве разделителя декларации).
Правильный подход зависит от того, хотите ли вы, чтобы ваше заявление было локальным или полным.
(* local declaration *)
let stevec = ref 0 in
let n = ref 1 in
(* toplevel declaration *)
let stevec = ref 0;;
let n = ref 1;;
Затем вы набрали while !n != 1 do
. Это не должно использоваться, поскольку вы выполняете физическое неравенство между целыми числами, тогда как вам требуется структурное равенство. Ну, это тоже будет работать из-за поведения OCaml по целым числам, но для хорошей практики вам нужно использовать <>
вместо !=
.
Теперь давайте посмотрим на теле вашего цикла в:
if (!n mod 2 = 0) then
stevec := !stevec + 1;
n := !n/2;
if (!n mod 2 = 1) then
stevec := !stevec + 1;
n := 3 * !n + 1;
Обратите внимание на отсутствии какой-либо fi
или закрывающей скобки? Это потому, что в OCaml выполняется только следующее выражение после then
. И приоритет над ;
не идет так, как вы этого хотите. Вы можете использовать parens или более явную конструкцию begin ... end
. Чтобы доказать, что работает begin ... end
, я заменил ваш второй тест на инструкцию else
.
if (!n mod 2 = 0) then
begin
stevec := !stevec + 1;
n := !n/2;
end
else
begin
stevec := !stevec + 1;
n := 3 * !n + 1;
end
Наконец while ... done
быть собой выражение, вы должны поставить ;
в конце.
И вот как вы удаляете ошибки из своего кода.
...
Это явно не «правильный путь» для этого в OCaml. Главным преимуществом FP является его близость к математике, и вы здесь пытаетесь определить математическую функцию. Итак, давайте сделаем это функциональным способом:
let is_even x = (x mod 2) = 0;;
let rec collatz counter n =
if n = 1
then counter
else collatz (counter+1) (if is_even n then n/2 else 3*n+1);;
let() =
for i = 1 to 100 do
print_int (collatz 0 i);
print_newline();
done;;
Не выглядит ли это лучше? Не стесняйтесь просить о каких-либо разъяснениях, конечно.
Я могу исправить ошибки синтаксиса, но когда я запустил код, он не завершился, поэтому я думаю, что в коде есть логические проблемы. –
Вы пытались использовать функциональное программирование вместо побочных эффектов? Если вы это сделаете, ваш код OCaml будет более читабельным и доступным для записи. – PatJ
Я просто изучаю Ocaml, но я уверен, что на языке, таком как java или python, эта логика должна работать ... – minus