Чтобы решить проблему с 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"
/>
Чтобы он работал, вам нужно передать $ factorial в качестве ссылки
$factorial = function( $n ) use ( &$factorial ) {
if( $n == 1 ) return 1;
return $factorial( $n - 1 ) * $n;
};
print $factorial( 5 );
Вы можете использовать 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
С анонимным классом (PHP 7 +), не определяя переменную:
echo (new class {
function __invoke($n) {
return $n < 2 ? 1 : $n * $this($n - 1);
}
})(5);
Я знаю, что это может быть непростой подход, но я узнал о технике под названием «исправить» из функциональных языков. Функция 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 является жизнеспособным подходом.