Examinons d'abord ce qu'est le vrai et le faux et ce qui leur donne un sens en premier lieu.
nous pouvons construire une structure appelée if a then b else c dans le calcul lambda comme suit:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
En JavaScript, cela ressemble à ceci:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
pour que ifThenElse soit utile, nous avons besoin d'une fonction "true" qui choisit soit la droite soit la gauche, et le fait en ignorant l'autre option, ou une fonction "false" qui choisit l'option "true" ne prend pas.
Nous pouvons définir ces fonctions comme suit:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
en JavaScript, cela ressemble à ceci:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
maintenant nous pouvons faire ce qui suit
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
avec doThis et doThat étant (\ a. ()) parce que le calcul lambda n'offre aucun service tel que l'impression / maths / chaînes, tout ce que nous pouvons faire est de ne rien faire et dire que nous l'avons fait (et plus tard tricher en le remplaçant par des services dans notre système qui fournit les effets secondaires que nous voulons)
alors voyons cela en action.
(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");})();
C'est un environnement profond qui pourrait être simplifié si nous étions autorisés à utiliser des tableaux / cartes / arguments / ou plus d'une instruction pour diviser en plusieurs fonctions, mais je veux garder c'est aussi pur que je peux me limiter aux fonctions d'exactement un argument seulement.
notez que le nom True / False n'a aucune signification inhérente, nous pouvons facilement les renommer en oui / non, gauche / droite, droite / gauche, zéro / un, pomme / orange. Cela a une signification en ce que quel que soit le choix qui est fait, il n'est causé que par le type de choix qui l'a fait. Donc, si "LEFT" est imprimé, nous savons que le sélecteur ne peut être que vrai, et sur la base de cette connaissance, nous pouvons guider nos décisions ultérieures.
Donc pour résumer
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');
})();