Skip to content

Instantly share code, notes, and snippets.

@dhil
Created September 13, 2019 03:00
Show Gist options
  • Save dhil/1a7579062da7caf511b8623d10cdddf4 to your computer and use it in GitHub Desktop.
Save dhil/1a7579062da7caf511b8623d10cdddf4 to your computer and use it in GitHub Desktop.
Typing the Y combinator in C#.
// 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