using System; using System.Diagnostics; class Program { public delegate TResult ParamsFunc(params T[] args); static class Y { class RecursiveFunction { public Func> o; public RecursiveFunction(Func> o) => this.o = o; } public static ParamsFunc y1( Func, ParamsFunc> f) { var r = new RecursiveFunction((RecursiveFunction w) => f((Args[] args) => w.o(w)(args))); return r.o(r); } } static ParamsFunc y2( Func, ParamsFunc> f) { Func> r = w => { Debug.Assert(w is Func>); return f((Args[] args) => w(w)(args)); }; return r(r); } static ParamsFunc y3( Func, ParamsFunc> f) => (Args[] args) => f(y3(f))(args); static void Main() { var factorialY1 = Y.y1((ParamsFunc fact) => (int[] x) => (x[0] > 1) ? x[0] * fact(x[0] - 1) : 1); var fibY1 = Y.y1((ParamsFunc fib) => (int[] x) => (x[0] > 2) ? fib(x[0] - 1) + fib(x[0] - 2) : 2); Console.WriteLine(factorialY1(10)); // 362880 Console.WriteLine(fibY1(10)); // 110 } }