如何在 lambda 演算中编码

How to encode in lambda calculus

我正在 Haskell 学习 lambda 演算,在此期间,我遇到了这个问题。

这些问题的答案是:

但我无法理解他们是如何得出答案的。 就像 eq,我不明白他们是怎么得出这个结论的:λab.a b (b (λxy.y) (λxy.x)) 和nand一样。如果有人解释一下并帮助我理解这个问题,那就太好了。

谢谢。

让我们先用实际数据类型编写有问题的函数(但没有模式匹配:只有if/then/else):

data Bool = False | True -- recall this definition
not  a   = if a then False else True
eq   a b = if a then (if b then True  else False)
                else (if b then False else True )
nand a b = if a then (if b then False else True )
                else (if b then True  else True )

如果您购买这些定义——非常简单,只是列出函数的真值表——那么我们就可以开始进行一些推理了。首先,我们可以稍微简化一下 eqnand 函数的外部分支:

eq   a b = if a then b else not b
nand a b = if a then not b else True

现在我们基本上完成了。我们只是将每个 FalseTrue 替换为它们的 if/then/else 行为,并替换每个 if/then /else 函数应用:

type Bool a = a -> a -> a
false a b = a -- `if False then a else b` becomes `false a b`
true  a b = b -- `if True  then a else b` becomes `true  a b`

not  a   = a false true   -- from `if a then False else True`
eq   a b = a b (not b)    -- from `if a then b else not b`
nand a b = a (not b) true -- from `if a then not b else True`

这些是您的解决方案中给出的定义,尽管公认的是 Haskell 语法而不是 lambda 演算语法。

我使用 Haskell 约定将 λ 写成 \

从评论来看,您似乎在这部分遇到了问题:

eq = \a b. a b (b (\x y. y) (\x y. x))

所以我只关注这个。

我们对布尔值的编码是作为带有两个参数的函数。 True return 是第一个参数,False return 是第二个参数。第一段直接给出编码:

True = \x y. x
False = \x y. y

直到最后我们都将使用名称而不是 lambda 表达式。

我们知道 eq 应该有两个参数,即要比较的两个布尔值。 (布尔值的编码本身有两个参数,但这是不同的——无论布尔值如何编码,eq 都应该有两个参数)所以我们知道它应该看起来像:

eq = \a b. _________________

在这一点上,我们几乎唯一能做的就是检查其中一个参数,以确定它是 True 还是 Falseeq 是对称的,所以我们问的是哪一个并不重要;让我们无缘无故地选择 a。根据编码,我们询问的方式是将两个参数传递给我们想要了解的事物。

eq = \a b. a ____ ____

我们还没有弄清楚 "holes" 中的内容。第一个洞是 return 如果 a 结果是 True,第二个洞是 return 如果结果是 False.

为了弄清楚如何填补这些漏洞,让我们写下我们试图定义的真相 table:

a     |   b   |  eq a b
------+-------+---------
True  | True  |  True
True  | False |  False
False | True  |  False
False | False |  True

请注意,在 aTrue 的两行中,a == b 列与 b 列完全相同。所以当 aTrue 时,我们只是 return b。所以我们可以填补其中一个漏洞:

eq = \a b. a b ____

现在注意 table 当 aFalse 时,a == bb 列相反,所以在这种情况下我们应该反转 b 和 return 它。

要反转 b,当 bTrue 时,我们希望它为 False,反之亦然。在编码中,即:

b False True

这就是我们应该 return 当 aFalse 时,所以我们填补另一个洞:

eq = \a b. a b (b False True)

现在我们只展开 FalseTrue

的定义
eq = \a b. a b (b (\x y. y) (\x y. x))

给你了。