Спочатку давайте вивчимо, що таке істинне та хибне, і що надає їм значення в першу чергу.
ми можемо побудувати структуру, яку називають, якщо тоді b ще c в обчисленні лямбда, таким чином:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
У JavaScript це виглядає приблизно так:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
для того, щоб ifThenElse був корисним, нам потрібна функція "true", яка вибирає правий чи лівий, і робить це, не зважаючи на інший варіант, або функція "false", яка вибирає варіант "true", не приймає.
Ми можемо визначити ці функції так:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
у JavaScript це виглядає так:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
тепер ми можемо зробити наступне
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
з doThis та doThat being (\ a. ()), оскільки обчислення лямбда не пропонує жодних послуг, таких як друк / математика / рядки, все, що ми можемо зробити, - нічого не робити і сказати, що ми це зробили (і пізніше накручуємо, замінивши його на сервіси в наша система, яка надає потрібні нам побічні ефекти)
тому давайте подивимось це на дію.
(function(True) {
return (function(False) {
return (function(ifThenElse) {
return (function(doThis) {
return (function(doThat) {
return ifThenElse(True)(doThis)(doThat);
});
});
});
})
})(function(a) {
return function(b) {
return a;
}
})(function(a) {
return function(b) {
return b;
}
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
})(function(a) { console.log("you chose LEFT!"); })
(function(a) {console.log("you chose RIGHT");})();
Це глибоке середовище, яке могло б бути спрощено, якби нам було дозволено використовувати масиви / карти / аргументи / або більше ніж одне твердження для поділу на кілька функцій, але я хочу, щоб це було таким чистим, наскільки я можу обмежувати себе функціями саме одного аргументу тільки.
зауважте, що ім'я True / False не має притаманного значення, ми можемо легко перейменувати їх на так / ні, ліво / право, право / ліво, нуль / один, яблуко / помаранчеве. Він має значення в тому, що який би вибір не був зроблений, він обумовлений лише тим видом, який він зробив. Отже, якщо надруковано "ВЛІВО", ми знаємо, що вибір може бути лише правдою, і на основі цих знань ми можемо керувати своїми подальшими рішеннями.
Отже, підсумовуючи
function ChooseRight(left) {
return function _ChooseRight_inner(right) {
return right;
}
}
function ChooseLeft(left) {
return function _ChooseLeft_inner(right) {
return left;
}
}
var env = {
'0': ChooseLeft,
'1': ChooseRight,
'false': ChooseRight,
'true': ChooseLeft,
'no': ChooseRight
'yes': ChooseLeft,
'snd': ChooseRight,
'fst': ChooseLeft
};
var _0 = env['0'];
var _1 = env['1'];
var _true = env['true'];
var _false = env['false'];
var yes = env['yes'];
var no = env['no'];
// encodes church zero or one to boolean
function lambda_encodeBoolean(self) {
return self(false)(true);
}
// decodes a Boolean to church zero or one
function lambda_decodeBoolean(self) {
console.log(self, self ? env['true'] : env['false']);
return self ? env['true'] : env['false'];
}
lambda_decodeBoolean('one' === 'two')(function() {
console.log('one is two');
})(function() {
console.log('one is not two');
})();
lambda_decodeBoolean('one' === 'one')(function() {
console.log('one is one');
})(function() {
console.log('one is not one');
})();