2016-07-03 4 views
1

Я пытаюсь создать простую функцию, которая может записывать вывод в файл, скажем file.txt. Вывод представляет собой таблицу умножения (как показано ниже).Использование OCaml для вывода простой таблицы умножения

Пример таблицы умножения, если функция аргумента 5: Example of the multiplication table if the function argument is 5

Проблема заключается в том, что OCaml просто зависает, когда я запускаю код (вероятно, из-за бесконечной рекурсии?). Я продолжаю смотреть через логику и, кажется, хорошо ..

(*n is the row counter and n2 is the column counter*) 
let rec row ch x n = 
    let rec column ch x n n2 = 
     (*If column counter reaches limit then stop here*) 
     if (n2 = x+1) 
     then() 
     else 
      output_string ch (string_of_int (n2*n)); 
      output_char ch '\t'; 
      column ch x n (n2+1) 
    in 
     column ch x n 1; 

     (*If row counter reaches limit then stop here*) 
     if n = x+1 
     then() 
     else 
      output_char ch '\n'; 
      row ch x (n+1);; 

Позже я называю строку в табличной функции, как это:

let rec table file x = 
    let ch = open_out file in 
     row ch x 1; 
     close_out ch;; 

Когда я бегу table "foo" 5, он просто зависает. Кроме того, в будущем, как я могу лучше обрабатывать такие ошибки? Любые рекомендуемые параметры отладки для OCaml?

ответ

3

У вас есть два случая одной и той же проблемы: else часть if/then/else управляет только одним выражением, но вы ожидаете, что она будет управлять несколькими выражениями.

В первом случае else просто контролирует output_string. Это означает, что остальная часть функции column будет выполнена во всех случаях. Это, по сути, бесконечная рекурсия.

Во втором случае else просто управляет output_char. Опять же, это дает вам бесконечную рекурсию.

Вы можете это исправить, добавив begin/end здесь:

begin 
output_string ch (string_of_int (n2*n)); 
output_char ch '\t'; 
column ch x n (n2+1) 
end 

И здесь:

begin 
output_char ch '\n'; row ch x (n+1) 
end 

После того как я сделать эти изменения, код работает для меня.

+0

Спасибо за ответ! Работал и для меня. Остается только контролировать выражение печати сразу после него из-за оператора с запятой? (оператор, если я правильно помню, выбрасывает выражение слева) –

+0

Да, другой способ взглянуть на это - это то, что 'then' и' else' имеют более высокий приоритет, чем ';'. Вы можете комбинировать несколько выражений другими способами, которые не требуют «begin/end». –

Смежные вопросы