almost there
This commit is contained in:
@@ -1,4 +1,53 @@
|
|||||||
module.exports = {
|
const nothing = require('./nothing.js');
|
||||||
to_int: (f) => f(n => n+1)(0),
|
|
||||||
to_boolean: (f) => f(true)(false),
|
const charset = '0123456789BFiuz';
|
||||||
|
const from_int = (n) => {
|
||||||
|
let f = nothing.ZERO;
|
||||||
|
for (let _ = 0; _ < n; _++) f = nothing.INC(f);
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
const to_int = (f) => nothing.TIMES(f)(i => i+1)(0);
|
||||||
|
const from_bool = (b) => b ? nothing.TRUE : nothing.FALSE;
|
||||||
|
const to_bool = (f) => f(true)(false);
|
||||||
|
const to_array = (l) => {
|
||||||
|
let a = [];
|
||||||
|
|
||||||
|
while (!to_bool(nothing.IS_EMPTY(l))) {
|
||||||
|
a.push(nothing.FIRST(l));
|
||||||
|
l = nothing.REST(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
const from_array = (a) => {
|
||||||
|
let l = nothing.EMPTY;
|
||||||
|
|
||||||
|
while (a.length) l = nothing.UNSHIFT(l)(a.pop());
|
||||||
|
|
||||||
|
return l;
|
||||||
|
};
|
||||||
|
const to_char = (c) => charset[to_int(c)];
|
||||||
|
const from_char = (c) => from_int(charset.indexOf(c));
|
||||||
|
const to_string = (s) => to_array(s).map(to_char).join('');
|
||||||
|
const from_string = (s) => from_array(s.split('').map(from_char));
|
||||||
|
const representation_of = (v) => {
|
||||||
|
if (typeof v == "number") return from_int(v);
|
||||||
|
if (typeof v == "boolean") return from_bool(v);
|
||||||
|
if (typeof v == "string") return from_string(v);
|
||||||
|
if (Array.isArray(v)) return from_array(v.map(representation_of));
|
||||||
|
throw Error(`Oops, I don’t know how represent this: ${v}`);
|
||||||
|
};
|
||||||
|
const zip = (a, b) => a.map((e, i) => [e, b[i]]);
|
||||||
|
const check_represent = function(r, v) {
|
||||||
|
if (typeof v == "number") return to_int(r) == v;
|
||||||
|
if (typeof v == "boolean") return to_bool(r) == v;
|
||||||
|
if (typeof v == "string") { console.log("checking ", to_array(r).map(to_int), " against ", v); return to_string(r) == v; }
|
||||||
|
if (Array.isArray(v)) {
|
||||||
|
let a = to_array(r);
|
||||||
|
return a.length == v.length && zip(a, v).every(([r, v]) => check_represent(r,v));
|
||||||
|
}
|
||||||
|
throw Error(`Oops, I don’t know how check this: ${v}`);
|
||||||
|
};
|
||||||
|
module.exports = {
|
||||||
|
to_string, to_array, representation_of, check_represent, to_int, to_char
|
||||||
};
|
};
|
||||||
|
70
nothing.js
70
nothing.js
@@ -18,37 +18,55 @@ const NOT = b => IF(b)(FALSE)(TRUE);
|
|||||||
const AND = a => b => IF(a)(IF(b)(TRUE)(FALSE))(FALSE);
|
const AND = a => b => IF(a)(IF(b)(TRUE)(FALSE))(FALSE);
|
||||||
const OR = a => b => IF(a)(TRUE)(IF(b)(TRUE)(FALSE));
|
const OR = a => b => IF(a)(TRUE)(IF(b)(TRUE)(FALSE));
|
||||||
const IS_ZERO = n => n(x => FALSE)(TRUE);
|
const IS_ZERO = n => n(x => FALSE)(TRUE);
|
||||||
const IS_LEQ = n => m => IS_ZERO(SUBTRACT(n)(m)); // we only have positive ints
|
const IS_LEQ = n => m => IS_ZERO(SUB(n)(m)); // we only have positive ints
|
||||||
const IS_EQ = n => m => AND(IS_LEQ(n)(m))(IS_LEQ(m)(n)); // this is stupid
|
const IS_EQ = n => m => AND(IS_LEQ(n)(m))(IS_LEQ(m)(n)); // this is stupid
|
||||||
// time to get recursive!
|
// time to get recursive!
|
||||||
const Y = f => (x => f(x(x)))(x => f(x(x))); // lazy recursion
|
const Y = f => (x => f(x(x)))(x => f(x(x))); // lazy recursion
|
||||||
const Z = f => (x => f(_ => x(x)(_)))(x => f(_ => x(x)(_))); // eager recursion
|
const Z = f => (x => f(_ => x(x)(_)))(x => f(_ => x(x)(_))); // eager recursion
|
||||||
const FACT = Z(f => n => IF(IS_ZERO(n))(ONE)(_ => MULT(n)(f(DEC(n)))(_)));
|
const FACT = Z(f => n => IF(IS_ZERO(n))(ONE)(_ => MULT(n)(f(DEC(n)))(_)));
|
||||||
const DIV = null;
|
const DIV = Z(f => n => m => IF(IS_LEQ(m)(n))(_ => INC(f(SUB(n)(m))(m))(_))(ZERO));
|
||||||
const MOD = null;
|
const MOD = Z(f => n => m => IF(IS_LEQ(m)(n))(_ => f(SUB(n)(m))(m)(_))(m));
|
||||||
const PAIR = null;
|
const PAIR = x => y => f => f(x)(y);
|
||||||
const LEFT = null;
|
const LEFT = p => p(x => y => x);
|
||||||
const RIGHT = null;
|
const RIGHT = p => p (x => y => y);
|
||||||
const EMPTY = null;
|
const EMPTY = PAIR(TRUE)(TRUE);
|
||||||
const UNSHIFT = null;
|
const UNSHIFT = l => x => PAIR(FALSE)(PAIR(x)(l));
|
||||||
const IS_EMPTY = null;
|
const IS_EMPTY = LEFT;
|
||||||
const FIRST = null;
|
const FIRST = l => LEFT(RIGHT(l));
|
||||||
const REST = null;
|
const REST = l => RIGHT(RIGHT(l));
|
||||||
const INJECT = null;
|
const INJECT = Z(f => l => x => g => IF(IS_EMPTY(l))(x)(_ => f(REST(l))(g(x)(FIRST(l)))(g)(_)));
|
||||||
const FOLD = null;
|
const FOLD = Z(f => l => x => g => IF(IS_EMPTY(l))(x)(_ => g(f(REST(l))(x)(g))(FIRST(l))(_)));
|
||||||
const MAP = null;
|
const MAP = k => f => FOLD(k)(EMPTY)(l => x => UNSHIFT(l)(f(x)));
|
||||||
const RANGE = null;
|
const RANGE = Z(f => n => m => IF(IS_LEQ(n)(m))(_ => UNSHIFT(f(INC(n))(m))(n)(_))(EMPTY));
|
||||||
const SUM = null;
|
const SUM = l => INJECT(l)(ZERO)(ADD);
|
||||||
const PROD = null;
|
const PROD = l => INJECT(l)(ONE)(MULT);
|
||||||
const CONCAT = null;
|
const CONCAT = k => l => FOLD(k)(l)(UNSHIFT);
|
||||||
const PUSH = null;
|
const PUSH = l => x => CONCAT(l)(UNSHIFT(EMPTY)(x));
|
||||||
const REVERSE = null;
|
const REVERSE = l => FOLD(l)(EMPTY)(PUSH);
|
||||||
const INC_ALL = null;
|
const INC_ALL = l => MAP(l)(INC);
|
||||||
const DOUBLE_ALL = null;
|
const DOUBLE_ALL = l => MAP(l)(MULT(TWO));
|
||||||
const TO_DIGITS = null;
|
const TEN = INC(MULT(THREE)(THREE));
|
||||||
const TO_STRING = null;
|
const RADIX = TEN;
|
||||||
const FIZZBUZZ = null;
|
const FOUR = INC(THREE);
|
||||||
|
const FIVE = INC(INC(THREE));
|
||||||
|
const FIFTEEN = MULT(THREE)(FIVE);
|
||||||
|
const FIZZ = MAP(UNSHIFT(UNSHIFT(UNSHIFT(UNSHIFT(EMPTY)(FOUR))(FOUR))(TWO))(ONE))(ADD(RADIX));
|
||||||
|
const BUZZ = MAP(UNSHIFT(UNSHIFT(UNSHIFT(UNSHIFT(EMPTY)(FOUR))(FOUR))(THREE))(ZERO))(ADD(RADIX));
|
||||||
|
const FIZZBUZZ = n => MAP(RANGE(ONE)(n))(m =>
|
||||||
|
IF(IS_ZERO(MOD(m)(FIFTEEN)))(
|
||||||
|
CONCAT(FIZZ)(BUZZ)
|
||||||
|
)(IF(IS_ZERO(MOD(m)(THREE)))(
|
||||||
|
FIZZ
|
||||||
|
)(IF(IS_ZERO(MOD(m)(FIVE)))(
|
||||||
|
BUZZ
|
||||||
|
)(
|
||||||
|
m
|
||||||
|
)))
|
||||||
|
);
|
||||||
module.exports = {
|
module.exports = {
|
||||||
ZERO, ONE, TWO, THREE, TIMES, INC, ADD, MULT, POWER, DEC, SUB, TRUE,
|
ZERO, ONE, TWO, THREE, TIMES, INC, ADD, MULT, POWER, DEC, SUB, TRUE,
|
||||||
FALSE, IF, NOT, AND, OR, IS_ZERO, IS_LEQ, IS_EQ, IS_LEQ, Y, Z, FACT
|
FALSE, IF, NOT, AND, OR, IS_ZERO, IS_LEQ, IS_EQ, IS_LEQ, Y, Z, FACT,
|
||||||
|
DIV, MOD, PAIR, LEFT, RIGHT, EMPTY, UNSHIFT, IS_EMPTY, FIRST, REST, INJECT,
|
||||||
|
FOLD, MAP, RANGE, SUM, PROD, CONCAT, PUSH, REVERSE, INC_ALL, DOUBLE_ALL,
|
||||||
|
TEN, RADIX, FOUR, FIVE, FIFTEEN, FIZZ, BUZZ, FIZZBUZZ
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user