Skip to content

Instantly share code, notes, and snippets.

@dhil
Created January 4, 2019 09:19
Show Gist options
  • Save dhil/06988c1001253118e4605380d589adf9 to your computer and use it in GitHub Desktop.
Save dhil/06988c1001253118e4605380d589adf9 to your computer and use it in GitHub Desktop.
Typing the Y combinator in Dart
// Typing the Y combinator in Dart.
class Fix<A> {
A Function(Fix<A>) f;
Fix.inject(this.f);
A Function(Fix<A>) get project => f;
}
// fix : (Fix<A> -> a) -> Fix<A>.
Fix<A> fix<A>(A Function(Fix<A>) f) => Fix.inject(f);
// Y : ((a -> b) -> a -> b) -> a -> b.
B Function(A) Y<A, B>(B Function(A) Function(B Function(A)) f) {
B Function(A) Function(Fix<B Function(A)>) abs =
(Fix<B Function(A)> x) => (A a) => f(x.project(x))(a);
Fix<B Function(A)> arg =
fix<B Function(A)>((Fix<B Function(A)> x) => (A a) => f(x.project(x))(a));
return abs(arg);
}
// fact : (int -> int) -> int -> int.
int Function(int) fact(int Function(int) self) =>
(int n) => n == 0 ? 1 : n * self(n - 1);
// A representation of natural numbers.
abstract class Nat {}
class Succ implements Nat {
Nat n;
Succ(this.n);
String toString() => "Succ($n)";
}
class Zero implements Nat {
Zero();
String toString() => "Zero";
}
// int2nat : (int -> nat) -> int -> nat.
Nat Function(int) int2nat(Nat Function(int) self) =>
(int n) => n == 0 ? Zero() : Succ(self(n-1));
void main() {
int result = Y<int, int>(fact)(6);
print("$result");
Nat natural = Y<int, Nat>(int2nat)(6);
print("$natural");
}
// Output:
// $ dart y.dart
// 720
// Succ(Succ(Succ(Succ(Succ(Succ(Zero))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment