Skip to content

Instantly share code, notes, and snippets.

@ken-okabe
Last active July 13, 2018 11:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ken-okabe/7eff694043f05524fad41154e32a249a to your computer and use it in GitHub Desktop.
Save ken-okabe/7eff694043f05524fad41154e32a249a to your computer and use it in GitHub Desktop.
{
const equalJSON = a => b => JSON.stringify(a) === JSON.stringify(b);
const logEq = a => b => {
const result = equalJSON(a)(b);
console.log(result);
return result;
};
const TYPE = Symbol();
const typeOf = t => x => x == null
? x
: Object.assign(x, {
[TYPE]: t
});
const isType = t => x => x == null
? false
: x[TYPE] === t;
const flatArray = (arr1) => arr1
.reduce((acc, val) => Array.isArray(val)
? [...acc, ...flatArray(val)]
: [...acc, val], []);
const flatList = ls => ls.map(l => isType(M)(l)
? flatList(l(EVAL)) : l);
//evaluation to be associative operation: flatten list
const evaluation = list => associative(list);
const associative = list => flatArray(flatList(list));
const identityType = f => { //left&right identity
const T = x => (x === T)
? T //left identity
: f(x);
return typed(T); //right identity
};
const typed = T => Object.assign(T, {
[TYPE]: T //right identity
});
const EVAL = Symbol();
const M = identityType( //Monoid type constructer
a => { // list accumulation recursion
const m = list => x => (x === EVAL)
? evaluation(list) // list() triggered to eval
: typeOf(M)(m([...list, x])); // data x joint
return m([])(a); //initial empty [] list and data a
}
);
//Validation================
console.log(
(M) //[Function: M]
);
console.log(
(M)(M)
);
console.log(
(M)(M)(M)
);
console.log(
(M)(M)(M)(M)
);
logEq(
(M)(M)
)(
(M)
); //true
logEq(
(M)(M)(M)
)(
(M)
); //true
logEq(
(M)(M)(M)(M)
)(
(M)
); //true
console.log(
(M)(EVAL) // []
);
console.log(
(M)(M)(EVAL) //[]
);
console.log(
(M)(M)(M)(EVAL) //[]
);
console.log(
(M)(M)(M)(M)(EVAL) //[]
);
const m = M(5);
//left identity
logEq(
(M)(m)
)(
(m)
); //true
//right identity
logEq(
(m)
)(
(m)(M)
); //true
console.log(
(M)(1)(2)(3) //{ [Function: n] isList: true }
);
logEq(
(M)(1)(2)(3)
)(
(M)(99)
); //true without evaluation
logEq(
(M)(1)(2)(3)(EVAL)
)(
(M)(99)(EVAL)
); //false with evaluation
console.log(
(M)(1)(2)(3)(EVAL) //[1, 2, 3]
);
console.log(
(M)(1)(M)(2)(3)(M)(EVAL) //[1, 2, 3]
);
logEq(
(M)(1)(2)(3)(EVAL) //[1,2,3]
)(
(M)(1)(M)(2)(3)(M)(EVAL) //[1,2,3]
); //true
console.log("associative----------------");
const a = (M)(1)(2)(3);
const b = (M)(4)(5)(6);
const c = (M)(99);
const ab = (a)(b);
const bc = (b)(c);
const abc1 = (ab)(c);
const abc2 = (a)(bc);
console.log("no eval yet----------------");
console.log(
(ab)(EVAL) //[1, 2, 3, 4, 5, 6]
);
console.log(
(bc)(EVAL) //[4, 5, 6, 99]
);
console.log(
(abc1)(EVAL) //[1, 2, 3, 4, 5, 6, 99]
);
console.log(
(abc2)(EVAL) //[1, 2, 3, 4, 5, 6, 99]
);
logEq(
(abc1)(EVAL)
)(
(abc2)(EVAL)
); // true for Associative law
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment