Lassen Sie uns zunächst untersuchen, was wahr und falsch ist und was ihnen überhaupt Bedeutung gibt.
Wir können eine Struktur konstruieren, die aufgerufen wird, wenn a dann b sonst c in der Lambda-Rechnung wie folgt ist:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
In JavaScript sieht dies folgendermaßen aus:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
Damit ifThenElse nützlich ist, benötigen wir eine Funktion "true", die entweder rechts oder links wählt und dies unter Ignorieren der anderen Option tut, oder eine Funktion "false", die die Option "true" auswählt, nicht.
Wir können diese Funktionen wie folgt definieren:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
In JavaScript sieht es so aus:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
Jetzt können wir Folgendes tun
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
Mit doThis und doThat (\ a. ()), da Lambda Calculus keine Dienste wie Drucken / Mathematik / Zeichenfolgen anbietet, können wir nur nichts tun und sagen, dass wir es getan haben (und später betrügen, indem wir es durch Dienste in ersetzen unser System, das die gewünschten Nebenwirkungen bietet)
Lassen Sie uns dies in Aktion sehen.
(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");})();
Das ist eine tiefe Umgebung, die vereinfacht werden könnte, wenn wir Arrays / Maps / Argumente / oder mehr als eine Anweisung verwenden könnten, um sie in mehrere Funktionen aufzuteilen, aber ich möchte sie so rein wie möglich halten, um mich auf Funktionen mit genau einem Argument zu beschränken nur.
Beachten Sie, dass der Name Wahr / Falsch keine inhärente Bedeutung hat. Wir können sie leicht in Ja / Nein, Links / Rechts, Rechts / Links, Null / Eins, Apfel / Orange umbenennen. Es ist insofern von Bedeutung, als die getroffene Wahl nur durch die Art der Wahl verursacht wird, die sie getroffen hat. Wenn also "LINKS" gedruckt wird, wissen wir, dass die Auswahl nur wahr sein kann, und basierend auf diesem Wissen können wir unsere weiteren Entscheidungen leiten.
Also um es zusammenzufassen
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');
})();