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

91 lines
2.4 KiB
C#

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