Per prima cosa esaminiamo cos'è vero e falso e cosa dà loro significato in primo luogo.
possiamo costruire una struttura chiamata se a then b else c nel calcolo lambda come segue:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
In JavaScript, si presenta così:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
affinché ifThenElse sia utile, abbiamo bisogno di una funzione "true" che scelga destra o sinistra, e lo fa ignorando l'altra opzione, o una funzione "false" che sceglie l'opzione "true" non accetta.
Possiamo definire queste funzioni come segue:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
in JavaScript è simile al seguente:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
ora possiamo fare quanto segue
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
con doThis e doThat essendo (\ a. ()) perché lambda calculus non offre alcun servizio come stampa / matematica / stringhe, tutto ciò che possiamo fare è non fare nulla e dire di averlo fatto (e successivamente imbrogliare sostituendolo con servizi in il nostro sistema che fornisce gli effetti collaterali che vogliamo)
quindi vediamo questo in azione.
(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");})();
Questo è un ambiente profondo che potrebbe essere semplificato se ci fosse permesso di usare array / mappe / argomenti / o più di un'istruzione per dividere in più funzioni, ma voglio mantenere è puro quanto posso limitarmi a funzioni di esattamente un argomento solo.
si noti che il nome Vero / Falso non ha alcun significato intrinseco, possiamo facilmente rinominarli in sì / no, sinistra / destra, destra / sinistra, zero / uno, mela / arancia. Ha un significato in quanto qualunque sia la scelta fatta, è causata solo dal tipo di scelta fatta. Quindi, se viene stampato "SINISTRA", sappiamo che il selezionatore potrebbe essere solo vero e, sulla base di questa conoscenza, possiamo guidare le nostre ulteriori decisioni.
Quindi per riassumere
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');
})();