-
-
Save dhil/1a7579062da7caf511b8623d10cdddf4 to your computer and use it in GitHub Desktop.
Typing the Y combinator in C#.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Typing the Y combinator in C#. | |
// $ mcs y.cs | |
// $ mono y.exe | |
// 720 | |
// Succ(Succ(Succ(Succ(Succ(Succ(Zero)))))) | |
using System; | |
class YCombinator { | |
class Fix<A> { | |
Func<Fix<A>, A> f; | |
public Fix(Func<Fix<A>, A> f) { | |
this.f = f; | |
} | |
public Func<Fix<A>,A> Unfix { | |
get => f; | |
} | |
} | |
// Y : ((A -> B) -> A -> B) -> A -> B | |
public static Func<A, B> Y<A,B>(Func<Func<A,B>, Func<A,B>> f) { | |
Func<Fix<Func<A,B>>,Func<A,B>> g = | |
(Fix<Func<A,B>> x) => | |
(A a) => f(x.Unfix(x))(a); | |
return g(new Fix<Func<A,B>>(g)); | |
} | |
// The factorial function. | |
static Func<Func<int,int>,Func<int,int>> Fact | |
= (Func<int, int> self) => | |
(int n) => n == 0 ? 1 : n * self(n - 1); | |
// A representation of natural numbers. | |
abstract class Nat {} | |
class Zero : Nat { | |
public Zero() {} | |
override public String ToString() => "Zero"; | |
} | |
class Succ : Nat { | |
Nat n; | |
public Succ(Nat n) { | |
this.n = n; | |
} | |
override public String ToString() { | |
return "Succ(" + n.ToString() + ")"; | |
} | |
} | |
static Func<Func<int,Nat>,Func<int,Nat>> Int2Nat | |
= (Func<int,Nat> self) => | |
(int n) => n == 0 ? (Nat)new Zero() : (Nat)new Succ(self(n-1)); | |
public static void Main(String[] args) { | |
int result0 = Y(Fact)(6); | |
Console.WriteLine(result0); | |
Nat result1 = Y(Int2Nat)(6); | |
Console.WriteLine(result1.ToString()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment