Хвостовая рекурсия и скалярные обещания


В настоящее время я играю с неблокирующими фьючерсами 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 3

2 ответа:

Ваш метод вовсе не рекурсивный. res - это вычисление, потенциально выполняемое в другом потоке. res map p flatMap f немедленно вернет обещание, что касается вашего метода. Повторение к repeat произойдет в другом процессе.

В несколько более кратких терминах, Promise является монадой продолжения, и flatMap вызовы автоматически переводятся в стиль передачи продолжения для вас.

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

Вы передаете рекурсию куда-то как анонимную функцию. Никто не знает, как часто это будет исполняться.