Анонимные рекурсивные функции PHP

Чтобы решить проблему с J2ee Spec, мне нужно было добавить кеш-уровень = 0 для входящего шлюза.

<int-jms:inbound-gateway 
    id="springbatch.master.inbound.gateway" 
    connection-factory="springbatch.jmsConnectionFactory" 
    request-channel="springbatch.slave.jms.request" 
    request-destination="springbatch.partition.jms.requestsQueue" 
    reply-channel="springbatch.slave.jms.response" 
    concurrent-consumers="${springbatch.partition.concurrent.consumers}" 
    max-concurrent-consumers="${springbatch.partition.concurrent.maxconsumers}" 
    max-messages-per-task="${springbatch.partition.concurrent.maxmessagespertask}"
    reply-time-to-live="${springbatch.partition.reply.time.to.live}"  
    cache-level="0"
/>
190
задан Wil Moore III 30 June 2013 в 12:39
поделиться

4 ответа

Чтобы он работал, вам нужно передать $ factorial в качестве ссылки

$factorial = function( $n ) use ( &$factorial ) {
    if( $n == 1 ) return 1;
    return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
342
ответ дан 23 November 2019 в 05:36
поделиться

Вы можете использовать Y Combinator в PHP 7.1+, как показано ниже:

function Y
($le)
{return
    (function ($f) 
     {return
        $f($f);
     })(function ($f) use ($le) 
        {return
            $le(function ($x) use ($f) 
                {return
                    $f($f)($x);
                });
        });
}

$le =
function ($factorial)
{return
    function
    ($n) use ($factorial)
    {return
        $n < 2 ? $n
        : $n * $factorial($n - 1);
    };
};

$factorial = Y($le);

echo $factorial(1) . PHP_EOL; // 1
echo $factorial(2) . PHP_EOL; // 2
echo $factorial(5) . PHP_EOL; // 120

Играть с ним: https://3v4l.org/7AUn2

Источник коды из: https://github.com/whitephp/the-little-phper/blob/master/src/chapter_9.php

0
ответ дан 23 November 2019 в 05:36
поделиться

С анонимным классом (PHP 7 +), не определяя переменную:

echo (new class {
    function __invoke($n) {
        return $n < 2 ? 1 : $n * $this($n - 1);
    }
})(5);
0
ответ дан 23 November 2019 в 05:36
поделиться

Я знаю, что это может быть непростой подход, но я узнал о технике под названием «исправить» из функциональных языков. Функция fix из Haskell более широко известна как комбинатор Y , который является одним из наиболее известных комбинаторов с фиксированной точкой .

Фиксированная точка - это значение, которое не изменяется функцией: фиксированной точкой функции f является любое x такое, что x = f (x). Комбинатор с фиксированной точкой y - это функция, которая возвращает фиксированную точку для любой функции f. Поскольку y (f) - неподвижная точка f, имеем y (f) = f (y (f)).

По сути, комбинатор Y создает новую функцию, которая принимает все аргументы оригинала, а также дополнительный аргумент, рекурсивную функцию. Как это работает, более очевидно, если использовать каррированную нотацию. Вместо того, чтобы писать аргументы в круглых скобках ( f (x, y, ...) ), запишите их после функции: f x y ... . Комбинатор Y определяется как Y f = f (Y f) ; или, с одним аргументом для рекурсивной функции, Y f x = f (Y f) x .

Поскольку PHP не выполняет автоматические функции curry , заставить работать fix - это своего рода хитрость, но я думаю, что это интересно.

function fix( $func )
{
    return function() use ( $func )
    {
        $args = func_get_args();
        array_unshift( $args, fix($func) );
        return call_user_func_array( $func, $args );
    };
}

$factorial = function( $func, $n ) {
    if ( $n == 1 ) return 1;
    return $func( $n - 1 ) * $n;
};
$factorial = fix( $factorial );

print $factorial( 5 );

Обратите внимание, что это почти то же самое, что и другие простые решения по закрытию, но функция fix создает закрытие за вас. Комбинаторы с фиксированной запятой немного сложнее, чем использование замыкания, но они более общие и имеют другое применение.Хотя метод закрытия больше подходит для PHP (который не является ужасно функциональным языком), исходная проблема - это больше упражнение, чем для производства, поэтому комбинатор Y является жизнеспособным подходом.

24
ответ дан 23 November 2019 в 05:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: