布尔SKI逻辑



我正在尝试grok组合子,所以我在Typescript:中编写了基本的组合子:KS

const K: Kestrel = a => b => a;
const S: Starling = a => b => c => a(c)(b(c));

然后,我关注了维基百科上关于SKI布尔逻辑的文章:

TRUE = K
FALSE = SK

因此:

const TRUE: True = K;
const FALSE = S(K);

这是通过了基本测试:

const t = () => true;
const f = () => false;
test('Ktf = (TRUE)tf = t', () => {
const actual = TRUE(t)(f)();
expect(actual).toBe(K(t)(f)());
expect(actual).toBe(true);
});
test('SKxy = y', () => {
expect(S(K)(t)(f)()).toBe(false);
expect(FALSE(t)(f)()).toBe(false);
});

到目前为止还不错,但当谈到NOT时,维基百科上说:

NOT = (FALSE)(TRUE) = (SK)(K)
(TRUE)NOT = TRUE(FALSE)(TRUE) = FALSE
(FALSE)NOT = FALSE(FALSE)(TRUE) = TRUE

我写了一个代码和测试,我得到了:

const NOT = S(K)(K);
test('(TRUE)NOT = FALSE', () => {
expect(TRUE(NOT)(t)(f)()).toBe(false); // <- see these () after (t)(f)?
expect(TRUE(NOT)(f)(t)()).toBe(true);
});
test('(FALSE)NOT = TRUE', () => {
expect(FALSE(NOT)(t)(f)).toBe(true); // <- here we don't have these ()
expect(FALSE(NOT)(f)(t)).toBe(false);
});

我的问题是关于我在评论中强调的两行:为什么要让测试通过,我需要TRUEFALSE之间的不对称?似乎我遵循了KS实现中的所有细节,但在TRUE(NOT)(t)(f)的情况下,我得到了函数() => false,在FALSE(NOT)(t)(f)的情况下我得到了false

是否有我遗漏的细节,或者维基百科的定义不够精确?

p.S.:这是代码:https://repl.it/repls/FuchsiaFuchsiaTruetype

两件事,1。您对NOT的实现是错误的,以及2。这种不对称纯属巧合。

1.巧合:

注意,TRUEFALSE都是curry函数,它们正在等待另外两个arg进行求值。

现在检查这个事实:

FALSE(NOT)(t) === t

FALSE实际上并不关心第一个arg,它所做的只是简单地返回第二个arg。所以你得到t作为返回值,当你做FALSE(NOT)(t)(f)时,你实际上是在调用t(f),其中f是无用的arg,它产生了true。因此,巧合。

2.NOT的实现

维基百科页面写NOT作为后缀运算符,但这只是他们用来写下这个想法的字面表达。在JS代码中,您不能编写相同的代码。

(T(NOT=T(F((T(=F

请注意,NOT被扩展为两个参数,然后传递给前面的函数。要在JS中实现这个想法,您需要编写:

const NOT = b => b(S(K))(K);

并将调用签名反转回正常形式:CCD_ 22。

我在这里修改了您的原始代码:https://repl.it/@hackape/知识型财富降级

最新更新