Skip to content

Instantly share code, notes, and snippets.

@adam-singer
Forked from vsavkin/lambda.dart
Created October 2, 2013 13:52
Show Gist options
  • Save adam-singer/6794146 to your computer and use it in GitHub Desktop.
Save adam-singer/6794146 to your computer and use it in GitHub Desktop.
//Y-Combinator
final Y = (f) =>
((x) => f((y) => x(x)(y)))
((x) => f((y) => x(x)(y)));
//booleans
final TRUE = (x) => (y) => x;
final FALSE = (x) => (y) => y;
final cond = (b) => b;
//pairs and lists
final pair = (x) => (y) => (f) => f(x)(y);
final left = (p) => p(TRUE);
final right = (p) => p(FALSE);
final empty = pair(TRUE)(TRUE);
final cons = (x) => (l) => pair(FALSE)(pair(x)(l));
final isEmpty = left;
final first = (l) => left(right(l));
final rest = (l) => right(right(l));
//numbers
final ZERO = (p) => (x) => x;
final ONE = (p) => (x) => p(x);
final TWO = (p) => (x) => p(p(x));
final THREE = (p) => (x) => p(p(p(x)));
final FOUR = (p) => (x) => p(p(p(p(x))));
final FIVE = (p) => (x) => p(p(p(p(p(x)))));
final SIX = (p) => (x) => p(p(p(p(p(p(x))))));
final SEVEN = (p) => (x) => p(p(p(p(p(p(p(x)))))));
final EIGHT = (p) => (x) => p(p(p(p(p(p(p(p(x))))))));
final NINE = (p) => (x) => p(p(p(p(p(p(p(p(p(x)))))))));
final TEN = (p) => (x) => p(p(p(p(p(p(p(p(p(p(x))))))))));
final slide = (p) => pair(right(p))(inc(right(p)));
final inc = (n) => (p) => (x) => p(n(p)(x));
final dec = (n) => left(n(slide)(pair(ZERO)(ZERO)));
final add = (m) => (n) => n(inc)(m);
final sub = (m) => (n) => n(dec)(m);
final multiply = (m) => (n) => n(add(m))(ZERO);
final isZero = (n) => n((_) => FALSE)(TRUE);
final isLessOrEqualTo = (m) => (n) => isZero(sub(m)(n));
final mod = Y((f) => (n) => (m) =>
cond(isLessOrEqualTo(n)(m))
((x) => f(n)(sub(m)(n))(x))
(m));
//higher-order functions
final compose = (f) => (g) => (x) => f(g(x));
final fold = Y((f) => (l) => (x) => (g) =>
cond(isEmpty(l))
(x)
((y) => g(f(rest(l))(x)(g))(first(l))(y)));
final map = (k) => (f) =>
fold(k)
(empty)
((l) => (x) =>
cons(f(x))(l));
final filter = (k) => (f) =>
fold(k)
(empty)
((l) => (x) =>
cond(f(x))
(cons(x)(l))
(l));
//utility functions to covert lambda-expressions to Dart primitives
toDartInteger(lambdaInteger) => lambdaInteger((n) => n + 1)(0);
toDartBoolean(lambdaBoolean) => lambdaBoolean(true)(false);
toDartList(list){
final res = [];
while(! toDartBoolean(isEmpty(list))){
res.add(toDartInteger(first(list)));
list = rest(list);
}
return res;
}
//example
main(){
final isEven = compose(isZero)(mod(TWO));
final list = cons(EIGHT)
(cons(SEVEN)
(cons(FIVE)
(cons(TWO)
(empty))));
final res = map(
filter(list)(isEven))
(multiply(TEN));
print(toDartList(res));
// The same program written in Dart
// [8,7,5,2].where((_) => _.isEven).map((_) => _ * 10).toList();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment