Хвостовая рекурсия и скалярные обещания
В настоящее время я играю с неблокирующими фьючерсами Scalaz aka. Обещает выделить. Я изо всех сил пытаюсь сделать следующую функцию хвост-рекурсивной:
@tailrec
private def repeat( res: Promise[I] ):Promise[I] =
res map p flatMap {
(b:Boolean) =>
if( b ) repeat( res flatMap f ) else res
}
Где p
- предикат с типом I=>Boolean
и f
- параллельная функция с
Тип I=>Promise[I]
.
Метод компилируется без аннотации.
Какие-нибудь намеки ? Спасибо
2 ответа:
Ваш метод вовсе не рекурсивный.
res
- это вычисление, потенциально выполняемое в другом потоке.res map p flatMap f
немедленно вернет обещание, что касается вашего метода. Повторение кrepeat
произойдет в другом процессе.В несколько более кратких терминах,
Promise
является монадой продолжения, иflatMap
вызовы автоматически переводятся в стиль передачи продолжения для вас.
Хотя это выглядит хвостовой рекурсивностью, поскольку вызов появляется только один раз в коде, у вас есть более одного рекурсивного вызова - по одному для каждого элемента в вашей коллекции. По крайней мере, это то, что видит компилятор. (Предположим, что это плоская карта на какой-то коллекции; я понятия не имею, что
p
возвращает)Вы передаете рекурсию куда-то как анонимную функцию. Никто не знает, как часто это будет исполняться.