Хвост-рекурсия и скалярные обещания
В настоящее время я играю с неблокирующими фьючерсами 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
возвращается)
Вы передаете рекурсию куда-то как анонимную функцию. Никто не знает, как часто это будет выполняться.