Я подумал, что добавлю, что если вы переписали код следующим образом, он будет работать нормально:
# let zero = 0;;
# let one = 1;;
# let rec fib i =
match i with
0 -> zero
| 1 -> one
| j -> fib (j - 2) + fib (j - 1);;
Фундаментальная проблема (как довольно хорошо объяснено в другом ответе)что вы можете создавать новые локальные переменные с тем же именем, что и глобальные переменные, и что с помощью любого имени переменной в левой части совпадения просто создается новая локальная переменная с таким именем и заполняется ею при сопоставлении.Точно так же, как j
- это новая локальная переменная, которая содержит все сопоставляемое, zero
.А тот факт, что он был ранее объявлен в большем объеме, игнорируется Ocaml (вот почему вы можете с радостью писать такие вещи, как
let x = 1;;
let x = 2 in let x = 3 in x;;
, что дает результат 3.