C to OCaml - если условия внутри цикла for OCaml - PullRequest
0 голосов
/ 21 октября 2018

Я пытаюсь переписать код C в OCaml.Однако я не уверен, как работать с множественными условиями if внутри цикла for в OCaml.Можете ли вы помочь мне понять, как это сделать?У меня есть код C и то, что я сделал в OCaml, который не работает.

Код C:

bool function1 (int x, int y, int movei, int sol[][], int xMove[], int yMove[], int n) 
{ 
    int i, next_x, next_y; 
    if (movei == n) 
        return true; 

    for (i = 0; i < n; i++) { 
        next_x = x + xMove[i]; 
        next_y = y + yMove[i]; 

        if (function2(next_x, next_y, sol)) { 
            sol[next_x][next_y] = movei; 

            if (function1(next_x, next_y, movei + 1, sol, xMove, yMove, n)) 
                return true; 
            else
                sol[next_x][next_y] = 0;
        } 
    } 

    return false; 
}

РЕДАКТИРОВАТЬ: OCamlcode

Я изменил свой код OCaml, основываясь на ответе glennsl, но компилятор жалуется на то, что '(' и ')' не соответствует и ожидается.

let rec function1 x y movei sol xMove yMove n =
if movei=n then true
else
    (
    for i=0 to n-1 do 
    (
        let next_x = x + xMove.(i) in
        let next_y = y + yMove.(i) in

            if (function2 next_x next_y sol) then 
            sol.(next_x).(next_y)<-movei in 
                (
                    if (function1 next_x next_y movei+1 sol xMove yMove n) then true
                    else sol.(next_x).(next_y)<-0
                )   
            else false  

    done;; )
)

Предыдущий код OCaml:

let rec function1 x y movei sol xMove yMove n =
if movei=n then true
else
    for i=0 to n-1 do
        let next_x = x + xMove.(i);
        let next_y = y + yMove.(i);

            if (function2 next_x next_y sol) then
                sol.(next_x).(next_y)<-movei;

                    if (function1 next_x next_y movei+1 sol xMove yMove n) then true
                    else sol.(next_x).(next_y)<-0

            else ()

    done;;

Компилятор сообщает «Синтаксическая ошибка» в последней строке кода OCaml, где done ;; равно.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Проблема в этом примере заключается в «возврате истины»;это фактически прерывает цикл for и всю рекурсию.

Один из способов отразить этот тип потока в императивном коде в ocaml - это использовать исключение.Таким образом, все return true; станет raise Found.return false; просто удаляется, и функция возвращает значение единицы.

Затем вы добавляете вторую функцию, которая выполняет

let function1 x y movei sol xMove yMove n =
    try
        function1 x y movei sol xMove yMove n;
        false
    with Found -> true

, чтобы восстановить исходный API.

0 голосов
/ 21 октября 2018

Есть несколько проблем с вашим кодом:

  1. Синтаксическая ошибка, которую вы получаете, вызвана тем, что первый else интерпретируется как принадлежащий первому if, оставляявторой else болтался.OCaml не чувствителен к отступам, поэтому вам необходимо заключить вложенные управляющие структуры в круглые скобки или begin и end, которые в точности совпадают с круглыми скобками, но выглядят лучше при разделении блоков кода.Хорошей идеей будет использование ocp-indent для автоматического отступа вашего кода так, как он будет интерпретироваться, что имеет приятный побочный эффект выявления таких ошибок:

  2. let x = yявляется только декларацией верхнего уровня, а точка с запятой - это не терминатор оператора, а оператор, который объединяет выражения в цепочку и отбрасывает результат первого.OCaml - это язык, основанный на выражениях, и хотя он поддерживает императивное программирование, он не имеет операторов.Вместо этого вы хотите использовать let x = y in z, который связывает результат вычисления y с именем x в выражении z.Просто замените точку с запятой после let s на in, тогда он будет работать.

  3. Ветви ваших выражений if возвращают различные значения.Большинство из них возвращает unit, но два из них возвращают bool, что является ошибкой типа, поскольку функция или любое другое выражение не может возвращать как unit, так и bool.Из кода C выглядит, что вы должны возвращать false везде, где вы сейчас возвращаете (), неявно (если выражение оценивается как ()) или явно.

  4. OCamlтакже не использует пробелы для группировки, и поэтому function1 next_x next_y movei+1 sol xMove yMove n будет интерпретироваться не так, как вы ожидаете, а скорее как (function1 next_x next_y movei) + (1 sol xMove yMove n) из-за того, что приоритет применения функции выше, чем у оператора +.Оберните move+1 в круглые скобки, чтобы сделать его единственным аргументом function1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...