В дополнение ко многим хорошим ответам здесь в этой теме, тот факт, что Scala не дает нам оптимизируемый хвостовой вызов комбинатора с фиксированной запятой, беспокоит меня так сильно, что я решил написать макрос для перевода Y-комбинатора-подобный вызов обычного идиоматического рекурсивного вызова (с оптимизацией хвостового вызова, конечно).Идея заключается в том, что вызов типа
fix[Int,Int]((next) => (y) => ...body...)
легко переводится в
({(input) =>
object next {
def apply(y:Int):Int = ...body...
}
next(input)
})
. Я включил реализацию макросов, ориентированную на Scala 2.11 (с незначительной настройкой, которая также должна работать с 2.10) в это суть .
С помощью этого макроса мы можем выполнять обычные рекурсивные задачи анонимно, не опасаясь переполнения стека, например:
import asia.blip.ymacro.YMacro._
(y[BigInt,BigInt]((xx) => (y) => if(y==1) 1 else y * xx(y-1)))(2000)
дает
res0: BigInt = 33162750924506332411753933805763240382811...