布尔 SKI 逻辑
Boolean SKI logic
我正在尝试 grok 组合器,所以我在 Typescript 中写了基本的:K
和 S
:
const K: Kestrel = a => b => a;
const S: Starling = a => b => c => a(c)(b(c));
然后,我关注了关于SKI Boolean Logic的维基百科文章:
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);
});
我的问题是关于我用注释突出显示的两行:为什么要使测试通过,我需要 TRUE
和 FALSE
之间的这种不对称?似乎我遵循了 K
和 S
实现中的所有细节,但在 TRUE(NOT)(t)(f)
的情况下,我得到了一个函数 () => false
,在 [=25= 的情况下] 我得到一个 false
.
有没有我遗漏的细节或者维基百科的定义不够精确?
P.S.:
这是代码:https://repl.it/repls/FuchsiaFuchsiaTruetype
有两点,1. 你对 NOT
的实现是错误的,2. 不对称纯属巧合。
1。巧合:
请注意,TRUE
和 FALSE
都是 curry 函数,它们正在等待另外两个参数进行计算。
现在检查这个事实:
FALSE(NOT)(t) === t
FALSE
实际上并不关心第一个参数,它所做的只是 return 第二个参数。因此,您将 t
作为 return 值,当您执行 FALSE(NOT)(t)(f)
时,您实际上是在调用 t(f)
,其中 f
是无用的 arg,它会产生 true
。如此巧合。
2。 NOT
的实施
维基百科页面将 NOT 写为后缀运算符,但这只是他们用来写下这个想法的文字表达。在 JS 代码中,您不能编写相同的代码。
(T)NOT = T(F)(T) = F
看到 NOT 被扩展为两个 args 传递给它之前的函数。在JS中实现这个想法,需要这样写:
const NOT = b => b(S(K))(K);
并将调用签名反转回正常形式:NOT(TRUE)
.
我在这里修改了你的原始代码:https://repl.it/@hackape/KnowledgeableWealthyDowngrade
我正在尝试 grok 组合器,所以我在 Typescript 中写了基本的:K
和 S
:
const K: Kestrel = a => b => a;
const S: Starling = a => b => c => a(c)(b(c));
然后,我关注了关于SKI Boolean Logic的维基百科文章:
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);
});
我的问题是关于我用注释突出显示的两行:为什么要使测试通过,我需要 TRUE
和 FALSE
之间的这种不对称?似乎我遵循了 K
和 S
实现中的所有细节,但在 TRUE(NOT)(t)(f)
的情况下,我得到了一个函数 () => false
,在 [=25= 的情况下] 我得到一个 false
.
有没有我遗漏的细节或者维基百科的定义不够精确?
P.S.: 这是代码:https://repl.it/repls/FuchsiaFuchsiaTruetype
有两点,1. 你对 NOT
的实现是错误的,2. 不对称纯属巧合。
1。巧合:
请注意,TRUE
和 FALSE
都是 curry 函数,它们正在等待另外两个参数进行计算。
现在检查这个事实:
FALSE(NOT)(t) === t
FALSE
实际上并不关心第一个参数,它所做的只是 return 第二个参数。因此,您将 t
作为 return 值,当您执行 FALSE(NOT)(t)(f)
时,您实际上是在调用 t(f)
,其中 f
是无用的 arg,它会产生 true
。如此巧合。
2。 NOT
的实施
维基百科页面将 NOT 写为后缀运算符,但这只是他们用来写下这个想法的文字表达。在 JS 代码中,您不能编写相同的代码。
(T)NOT = T(F)(T) = F
看到 NOT 被扩展为两个 args 传递给它之前的函数。在JS中实现这个想法,需要这样写:
const NOT = b => b(S(K))(K);
并将调用签名反转回正常形式:NOT(TRUE)
.
我在这里修改了你的原始代码:https://repl.it/@hackape/KnowledgeableWealthyDowngrade