Najpierw zbadajmy, co jest prawdą, a co fałszem i co nadaje im znaczenie.
możemy skonstruować strukturę o nazwie if a then b else c w rachunku lambda w następujący sposób:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
W JavaScript wygląda to tak:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
aby ifThenElse było użyteczne, potrzebujemy funkcji „true”, która wybiera prawo lub lewo i robi to, ignorując drugą opcję, lub funkcja „false”, która wybiera opcję „true”, nie przyjmuje.
Możemy zdefiniować te funkcje w następujący sposób:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
w JavaScript wygląda to tak:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
teraz możemy wykonać następujące czynności
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
z doThis i doThat jest (\ a. ()) ponieważ rachunek lambda nie oferuje żadnych usług, takich jak drukowanie / matematyka / ciągi znaków, wszystko, co możemy zrobić, to nic nie robić i powiedzieć, że to zrobiliśmy (a później oszukiwać, zastępując to usługami w nasz system, który zapewnia pożądane efekty uboczne)
zobaczmy to w akcji.
(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");})();
To głębokie środowisko, które można by uprościć, gdyby pozwolono nam używać tablic / map / argumentów / lub więcej niż jednej instrukcji do podziału na wiele funkcji, ale chcę, aby było tak czyste, jak tylko mogę, ograniczając się do funkcji dokładnie jednego argumentu tylko.
zauważ, że nazwa Prawda / Fałsz nie ma żadnego wewnętrznego znaczenia, możemy łatwo zmienić ich nazwę na tak / nie, lewo / prawo, prawo / lewo, zero / jeden, jabłko / pomarańcza. Ma to znaczenie w tym, że dokonany wybór jest spowodowany jedynie rodzajem dokonanego wyboru. Jeśli więc wydrukowano „LEFT”, wiemy, że wybór może być tylko prawdziwy i na podstawie tej wiedzy możemy kierować naszymi dalszymi decyzjami.
Podsumowując
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');
})();