Primero examinemos qué es verdadero y falso y qué les da significado en primer lugar.
podemos construir una estructura llamada if a then b else c en cálculo lambda de la siguiente manera:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
En JavaScript, esto se ve así:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
para que ifThenElse sea útil, necesitamos una función "true" que elija derecha o izquierda, y lo hace mientras ignora la otra opción, o una función "false" que elige la opción "true" no toma.
Podemos definir estas funciones de la siguiente manera:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
en JavaScript se ve así:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
ahora podemos hacer lo siguiente
(\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 y doThat siendo (\ a. ()) porque el cálculo lambda no ofrece ningún servicio como impresión / matemática / cadenas, todo lo que podemos hacer es no hacer nada y decir que lo hicimos (y luego hacer trampa reemplazándolo con servicios en nuestro sistema que proporciona los efectos secundarios que queremos)
así que veamos esto en acción.
(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");})();
Ese es un entorno profundo que podría simplificarse si se nos permitiera usar matrices / mapas / argumentos / o más de una declaración para dividir en múltiples funciones, pero quiero mantenerlo tan puro como puedo limitarme a las funciones de exactamente un argumento solamente.
tenga en cuenta que el nombre Verdadero / Falso no tiene un significado inherente, podemos cambiarles el nombre fácilmente a sí / no, izquierda / derecha, derecha / izquierda, cero / uno, manzana / naranja. Tiene importancia porque cualquier elección que se haga, solo es causada por el tipo de elección que se hizo. Por lo tanto, si se imprime "IZQUIERDA", sabemos que el seleccionador solo puede ser verdadero y, en base a este conocimiento, podemos guiar nuestras decisiones adicionales.
Entonces para resumir
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');
})();