RosettaCodeData/Task/Y-combinator/C-sharp/y-combinator-13.cs
2020-02-17 23:21:07 -08:00

49 lines
1.7 KiB
C#

using System;
static class Program {
interface Function<T, R> {
R apply(T t);
}
interface RecursiveFunction<F> : Function<RecursiveFunction<F>, F> {
}
static class Functions {
class Function<T, R> : Program.Function<T, R> {
readonly Func<T, R> _inner;
public Function(Func<T, R> inner) => this._inner = inner;
public R apply(T t) => this._inner(t);
}
class RecursiveFunction<F> : Function<Program.RecursiveFunction<F>, F>, Program.RecursiveFunction<F> {
public RecursiveFunction(Func<Program.RecursiveFunction<F>, F> inner) : base(inner) {
}
}
public static Program.Function<T, R> Create<T, R>(Func<T, R> inner) => new Function<T, R>(inner);
public static Program.RecursiveFunction<F> Create<F>(Func<Program.RecursiveFunction<F>, F> inner) => new RecursiveFunction<F>(inner);
}
static Function<A, B> Y<A, B>(Function<Function<A, B>, Function<A, B>> f) {
var r = Functions.Create<Function<A, B>>(w => f.apply(Functions.Create<A, B>(x => w.apply(w).apply(x))));
return r.apply(r);
}
static void Main(params String[] arguments) {
Function<int, int> fib = Y(Functions.Create<Function<int, int>, Function<int, int>>(f => Functions.Create<int, int>(n =>
(n <= 2)
? 1
: (f.apply(n - 1) + f.apply(n - 2))))
);
Function<int, int> fac = Y(Functions.Create<Function<int, int>, Function<int, int>>(f => Functions.Create<int, int>(n =>
(n <= 1)
? 1
: (n * f.apply(n - 1))))
);
Console.WriteLine("fib(10) = " + fib.apply(10));
Console.WriteLine("fac(10) = " + fac.apply(10));
}
}