首先让我们来看看什么是真假,以及是什么赋予了它们意义。
我们可以在 lambda 演算中构造一个名为 if a then b else c 的结构,如下所示:
(\ifThenElse. <use if then else>)(\a. \b. \c. a b c)
在 JavaScript 中,这看起来像这样:
(function(ifThenElse) {
// use ifThenElse
})(function(a) {
return function(b) {
return function(c) {
return a(b)(c);
};
};
});
为了使 ifThenElse 有用,我们需要一个函数“true”来选择右或左,并在忽略另一个选项的情况下这样做,或者选择选项“true”的函数“false”不拿走。
我们可以这样定义这些函数:
(\true. <use true>)(\a. \b. a) and (\false. <use false>)(\a. \b. b)
在 JavaScript 中是这样的:
(function(True) {
// use True
})(function(a) {
return function(b) {
return a;
}
});
(function(False) {
// use True
})(function(a) {
return function(b) {
return b;
}
});
现在我们可以做以下事情了
(\true. \false. \ifThenElse. \doThis. \doThat. ifThenElse true doThis doThat)
(\a. \b. a)(\a. \b. b)(\a. \b. \c. a b c)(\a. ())(\a. ())
doThis 和 doThat 是 (\a. ()) 因为 lambda 演算不提供任何服务,例如打印/数学/字符串,我们所能做的就是什么都不做,说我们做了(然后通过替换它来作弊)在我们的系统中提供我们想要的副作用的服务)
让我们来看看它的实际效果。
(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");})();
如果我们被允许使用数组/映射/参数/或多个语句来拆分为多个函数,这是一个可以简化的深层环境,但我想保持尽可能纯洁,我可以将自己限制在以下函数中只有一个参数。
请注意名称 True/False 没有内在意义,我们可以轻松地将它们重命名为 yes/no、left/right、right/left、0/one、apple/orange。它的意义在于,无论做出什么选择,都只是由做出它的选择者的种类造成的。因此,如果打印“LEFT”,我们知道选择器只能是真的,并且基于这些知识我们可以指导我们进一步的决策。
总结一下
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');
})();