// константы
const constant = a => (f = x => x) => f(a);
const one = constant(1);
const two = constant(2);
const three = constant(3);
const five = constant(5);
const six = constant(6);
const eight = constant(8);
// операции
const plus = b => a => a + b;
const minus = b => a => a - b;
const times = b => a => a * b;
const dividedBy = b => a => a / b;
// тесты
console.log(three(times(five()))); // return 15
console.log(eight(minus(two()))); // return 6
console.log(one(plus(six(dividedBy(three()))))); // return 3
Сообщение от j0hnik
|
Самая вложенная [функция] будет выполняться раньше, из-за этого мы получаем такой результат [...] 5-(2-(2-1))
|
Слова
j0hnik относятся и к моему коду. Редукция выражения происходит справа налево, и не учитывается приоритет операторов... Почему бы сначала не получить выражение, а только затем его вычислить...
// константы
const constant = a => (f = x => x) => ({
[Symbol.toPrimitive](hint) {
return eval(this.valueOf());
},
valueOf() {
return f(a);
},
toString() {
return this[Symbol.toPrimitive]("string");
}
});
const one = constant(1);
const two = constant(2);
const three = constant(3);
const five = constant(5);
const six = constant(6);
const eight = constant(8);
// операции
const operator = sign => b => a => `${a.valueOf()} ${sign} ${b.valueOf()}`;
const plus = operator("+");
const minus = operator("-");
const times = operator("*");
const dividedBy = operator("/");
// тесты
alert([
three(times(five())), // 3 * 5
eight(minus(two())), // 8 - 2
one(plus(six(dividedBy(three())))), // 1 + 6 / 3
five(minus(two(minus(two(minus(one())))))) // 5 - 2 - 2 - 1
]);