Сначала давайте рассмотрим, что такое истина и ложь и что дает им смысл в первую очередь.
мы можем построить структуру, называемую, если a затем 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. <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 is (\ 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 не имеет присущего значения, мы можем легко переименовать их в yes / no, влево / вправо, right / left, zero / one, apple / orange. Это имеет значение в том, что какой бы выбор не был сделан, он вызван только тем, кто его сделал. Поэтому, если напечатано «LEFT», мы знаем, что выбор может быть только правдой, и на основе этого знания мы можем руководствоваться нашими дальнейшими решениями.
Итак, подведем итог
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');
})();