Last active
September 12, 2021 21:42
-
-
Save arian/9fa076e037334bf195da to your computer and use it in GitHub Desktop.
Church Numerals, Booleans, Pairs and Lists in JavaScript (ES6)
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
// conversions | |
let c2i = x => x(y => y + 1, 0) | |
let c2star = x => x(y => y + '*', '') | |
let c2b = x => x('True', 'False') | |
let c2a = xs => xs((y, ys) => [c2i(y)].concat(ys), []) | |
// numbers | |
let zero = (s,z) => z | |
let one = (s,z) => s(z) | |
let two = (s,z) => s(s(z)) | |
let three = (s,z) => s(s(s(z))) | |
// booleans | |
let t = (a,b) => a | |
let f = (a,b) => b | |
// boolean operators | |
let and = (x,y) => (a,b) => x(y(a, b), b) | |
let or = (x,y) => (a,b) => x(a, y(a, b)) | |
let not = x => (a,b) => x(b, a) | |
// pair | |
let pair = (a,b) => s => s(a, b) | |
let fst = x => x((a, b) => a) | |
let snd = x => x((a, b) => b) | |
// number operations | |
// successor | |
let succ = x => (s,z) => s(x(s, z)) | |
// adding | |
let add = (x,y) => x(p => succ(p, one), y) | |
// multiplying | |
let mul = (x,y) => x(p => add(p, y), zero) | |
// exponent | |
let exp = (x,y) => y(p => mul(p, x), one) | |
// decrease | |
let dec = n => fst(n(b => pair(snd(b), succ(snd(b))), pair(zero, zero))) | |
// subtract | |
let sub = (x,y) => y(p => dec(p), x) | |
// zero test | |
let iszero = x => x(_ => f, t) | |
// compare | |
let lt = (x, y) => and(iszero(sub(x, y)), not(iszero(sub(y, x)))) | |
let leq = (x,y) => iszero(sub(x, y)) | |
let eq = (x,y) => and(iszero(sub(x, y)), iszero(sub(y, x))) | |
let geq = (x,y) => not(lt(x,y)) | |
let gt = (x,y) => not(leq(x,y)) | |
// lists | |
let nil = (s, z) => z | |
let isnil = xs => xs(_ => f, t) | |
let cons = (x, xs) => (s,z) => s(x, xs(s, z)) | |
let head = xs => (s, z) => xs((y, ys) => y(s, z)) | |
let tail = xs => fst(xs((y, ys) => pair(snd(ys), cons(y, snd(ys))), pair(nil, nil))) | |
// logging | |
let logi = x => console.log(x.toString().slice(24, -3), c2i(x())) | |
let logb = x => console.log(x.toString().slice(24, -3), c2b(x())) | |
let loga = x => console.log(x.toString().slice(24, -3), c2a(x())) | |
logi(_ => zero) | |
logi(_ => one) | |
logi(_ => two) | |
logi(_ => add(one, succ(two))) | |
logi(_ => mul(two, three)) | |
logi(_ => exp(three, two)) | |
logi(_ => dec(two)) | |
logi(_ => sub(exp(two, three), two)) | |
logb(_ => not(t)) | |
logb(_ => not(f)) | |
logb(_ => and(t, t)) | |
logb(_ => and(f, t)) | |
logb(_ => and(t, f)) | |
logb(_ => and(f, f)) | |
logb(_ => or(t, t)) | |
logb(_ => or(f, t)) | |
logb(_ => or(t, f)) | |
logb(_ => or(f, f)) | |
logb(_ => iszero(zero)) | |
logb(_ => iszero(one)) | |
logb(_ => iszero(two)) | |
logb(_ => eq(one, two)) | |
logb(_ => eq(two, two)) | |
logb(_ => eq(two, one)) | |
logb(_ => leq(one, two)) | |
logb(_ => leq(two, two)) | |
logb(_ => leq(two, one)) | |
logb(_ => lt(one, two)) | |
logb(_ => lt(two, two)) | |
logb(_ => lt(two, one)) | |
logb(_ => geq(one, two)) | |
logb(_ => geq(two, two)) | |
logb(_ => geq(two, one)) | |
logb(_ => gt(one, two)) | |
logb(_ => gt(two, two)) | |
logb(_ => gt(two, one)) | |
loga(_ => nil) | |
loga(_ => cons(one, nil)) | |
loga(_ => cons(two, cons(one, nil))) | |
logb(_ => isnil(nil)) | |
logb(_ => isnil(cons(one, nil))) | |
logi(_ => head(cons(two, nil))) | |
loga(_ => tail(cons(zero, cons(one, cons(two, nil))))) | |
console.log(c2star(add(two, succ(two)))) | |
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
"_zero" | |
0 | |
"_one" | |
1 | |
"_two" | |
2 | |
"_add(_one, _succ(_two))" | |
4 | |
"_mul(_two, _three)" | |
6 | |
"_exp(_three, _two)" | |
9 | |
"_dec(_two)" | |
1 | |
"_sub(_exp(_two, _three), _two)" | |
6 | |
"_not(_t)" | |
"False" | |
"_not(_f)" | |
"True" | |
"_and(_t, _t)" | |
"True" | |
"_and(_f, _t)" | |
"False" | |
"_and(_t, _f)" | |
"False" | |
"_and(_f, _f)" | |
"False" | |
"_or(_t, _t)" | |
"True" | |
"_or(_f, _t)" | |
"True" | |
"_or(_t, _f)" | |
"True" | |
"_or(_f, _f)" | |
"False" | |
"_iszero(_zero)" | |
"True" | |
"_iszero(_one)" | |
"False" | |
"_iszero(_two)" | |
"False" | |
"_eq(_one, _two)" | |
"False" | |
"_eq(_two, _two)" | |
"True" | |
"_eq(_two, _one)" | |
"False" | |
"_leq(_one, _two)" | |
"True" | |
"_leq(_two, _two)" | |
"True" | |
"_leq(_two, _one)" | |
"False" | |
"_lt(_one, _two)" | |
"True" | |
"_lt(_two, _two)" | |
"False" | |
"_lt(_two, _one)" | |
"False" | |
"_geq(_one, _two)" | |
"False" | |
"_geq(_two, _two)" | |
"True" | |
"_geq(_two, _one)" | |
"True" | |
"_gt(_one, _two)" | |
"False" | |
"_gt(_two, _two)" | |
"False" | |
"_gt(_two, _one)" | |
"True" | |
"_nil" | |
[] | |
"_cons(_one, _nil)" | |
[1] | |
"_cons(_two, _cons(_one, _nil))" | |
[2, 1] | |
"_isnil(_nil)" | |
"True" | |
"_isnil(_cons(_one, _nil))" | |
"False" | |
"_head(_cons(_two, _nil))" | |
2 | |
"_tail(_cons(_zero, _cons(_one, _cons(_two, _nil))))" | |
[1, 2] | |
"*****" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment