как писать взаимно рекурсивные функции в Haxe

#recursion #haxe #mutual-recursion

#рекурсия #haxe #взаимная рекурсия

Вопрос:

Я пытаюсь написать простую взаимно рекурсивную функцию в Haxe 3, но не смог получить код для компиляции, потому что какая бы из взаимных функций, которая появляется первой, сообщит, что другие функции в группе не определены. Ниже приведен минимальный пример, в котором взаимно определенные функции odd и even используются для определения четности.

 static public function test(n:Int):Bool  {
    var a:Int;
    if (n >= 0) a = n; else a = -n;

    function even(x:Int):Bool {
        if (x == 0)
            return true;
        else
            return odd(x - 1);
    }
    function odd(x:Int):Bool {
        if (x == 0)
            return false;
        else
            return even(x - 1);
    }
    return even(a);
}
 

Попытка скомпилировать его в neko дает:

 ../test.hx:715: characters 11-14 : Unknown identifier : odd
Uncaught exception - load.c(181) : Module not found : main.n
 

Я попытался дать прямое объявление odd before even , как это было бы сделано в c / c , но, похоже, это незаконно в haxe3. Как можно определить взаимно рекурсивные функции, подобные приведенным выше? Возможно ли это вообще?

Примечание: я хотел, чтобы оба odd и even были локальными функциями, обернутыми в глобально видимую функцию test .

Спасибо,

Ответ №1:

Вместо того, чтобы использовать function myFn() {} синтаксис для локальной переменной, вы можете использовать myFn = function() {} синтаксис. Тогда вы сможете объявлять обозначения типов функций перед их использованием.

Теперь ваш код должен выглядеть так:

 static public function test(n:Int):Bool  {
    var a:Int;
    if (n >= 0) a = n; else a = -n;

    var even:Int->Bool = null;
    var odd = null; // Leave out the type signiature, still works.
    even = function (x:Int):Bool {
        if (x == 0)
            return true;
        else
            return odd(x - 1);
    }
    odd = function (x:Int):Bool {
        if (x == 0)
            return false;
        else
            return even(x - 1);
    }
    return even(a);
}
 

Это работает, потому что Haxe просто нужно знать, что even и odd существует, и устанавливается на что-то (даже если оно равно нулю), прежде чем они будут использоваться. Мы знаем, что мы установим для них обоих вызываемые функции до их фактического вызова.

Смотрите, как попробовать haxe: http://try.haxe.org/#E79D4

Комментарии:

1.Спасибо, Джейсон. Это близко. Но я все еще получаю сообщение об ошибке, жалующееся odd на то, что оно не инициализировано. ../test.hx:725: characters 19-22 : Local variable odd used without being initialized Uncaught exception - load.c(181) : Module not found : main.n

2. Извините, я должен был протестировать этот код. Это должно быть var even=null , var odd=null . Haxe слишком тщателен для его же блага. Я отредактирую свой ответ.