Created
January 4, 2019 09:19
-
-
Save dhil/06988c1001253118e4605380d589adf9 to your computer and use it in GitHub Desktop.
Typing the Y combinator in Dart
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 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