Хвост-рекурсия и скалярные обещания - PullRequest
3 голосов
/ 09 мая 2011

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

4 голосов
/ 10 мая 2011

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

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

1 голос
/ 09 мая 2011

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

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

...