Skip to content

Instantly share code, notes, and snippets.

@wreulicke
Last active August 28, 2016 15:43
Show Gist options
  • Save wreulicke/495420b6417e3675186dc82ab1395eae to your computer and use it in GitHub Desktop.
Save wreulicke/495420b6417e3675186dc82ab1395eae to your computer and use it in GitHub Desktop.
Promise
export type predicate= (...args: any[]) => boolean
const AND = (...predicates: predicate[]) =>
(...args: any[]) => predicates.every(predicate => predicate(...args));
const OR = (...predicates: predicate[]) =>
(...args: any[]) => predicates.some(predicate => predicate(...args));
const NOT = (predicate: predicate) => (...args: any[]) => !predicate(...args);
const EVERY = AND;
const SOME = OR;
const ANY = OR;
const XOR = (p1: predicate, p2: predicate) => (...args: any[]) => p1(...args) && !p2(...args) || !p1(...args) && p2(...args);
let Predict = function(predicate: predicate){
function IPredicate(...args: any[]) {
return predicate(...args);
}
Object.defineProperty(IPredicate, 'AND', {
value: function(...predicates: predicate[] ){
return Predict(AND(IPredicate, ...predicates));
}
});
Object.defineProperty(IPredicate, 'OR', {
value: function(...predicates: predicate[] ){
return Predict(OR(IPredicate, ...predicates));
}
});
Object.defineProperty(IPredicate, 'NOT', {
value: function(){
return Predict(NOT(IPredicate));
}
});
Object.defineProperty(IPredicate, 'XOR', {
value: function (p1: predicate, p2: predicate) {
return Predict(XOR(p1, p2));
}
});
return IPredicate;
};
export type predicate = ((...args: any[]) => Promise<boolean>)|((...args: any[]) => boolean)
const promisePredicate = (predicate: predicate) => {
return (...args: any[]) => {
const result = predicate(...args);
return typeof result === 'boolean' ?
new Promise((resolve: any, reject: any) => result ? resolve(args) : reject(args))
: new Promise((resolve: any, reject: any) => result.then((flag: boolean) => flag ? resolve(args) : reject(args), () => reject(args)));
};
};
const AND = (first: predicate, ...predicates: predicate[]) =>
(...args: any[]) => predicates.reduce((result, predicate) => result.then(() => promisePredicate(predicate)(...args)), promisePredicate(first)(...args));
const OR = (first: predicate, ...predicates: predicate[]) =>
(...args: any[]) => predicates.reduce((result, predicate) => result.catch(() => promisePredicate(predicate)(...args)), promisePredicate(first)(...args));
const NOT = (predicate: predicate) => (...args: any[]) =>
new Promise((resolve: any, reject: any) => promisePredicate(predicate)(...args).then(() => reject(args), () => resolve(args)));
const XOR = (p1: predicate, p2: predicate) => (...args: any[]) => OR(AND(p1, NOT(p2)), AND(NOT(p1), p2))(...args);
let Predict = function(predicate: predicate){
function IPredicate(...args: any[]) {
return promisePredicate(predicate)(...args);
}
Object.defineProperty(IPredicate, 'AND', {
value: function(...predicates: predicate[] ){
return Predict(AND(IPredicate, ...predicates));
}
});
Object.defineProperty(IPredicate, 'OR', {
value: function(...predicates: predicate[] ){
return Predict(OR(IPredicate, ...predicates));
}
});
Object.defineProperty(IPredicate, 'NOT', {
value: function(){
return Predict(NOT(IPredicate));
}
});
Object.defineProperty(IPredicate, 'XOR', {
value: function (p1: predicate, p2: predicate) {
return Predict(XOR(p1, p2));
}
});
return IPredicate;
};
export default {
AND,
OR,
NOT,
XOR,
Predict
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment