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

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

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

Другие вопросы по тегам