Вот ответ, аналогичный предоставленному @hvd, но с использованием оператора Y
, определенного здесь , это устраняет необходимость в локальных переменных:
public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
{
return t => f(Y(f))(t);
}
var halves = Y<double, IEnumerable<double>>(self => d => new[] { 0d }.SelectMany(_ => new[] { d }.Concat(self(d / 2))));
Anпример использования будет:
foreach (var half in halves(20))
Console.WriteLine(half);
, который выдаст 20, 10, 5, 2.5 и т. д.
Я бы не советовал использовать это в рабочем коде, но это весело.
Оператор Y
также допускает другие рекурсивные лямбда-выражения, например:
var fibonacci = Y<int, int>(self => n => n > 1 ? self(n - 1) + self(n - 2) : n);
var factorial = Y<int, int>(self => n => n > 1 ? n * self(n - 1) : n);
var hanoi = Y<int, int>(self => n => n == 1 ? 1 : 2 * self(n - 1) + 1);