我目前正在学习Haskell,还参加了一个关于大学函数式编程的理论讲座。
我知道这纯粹是理论/学术问题,但我感兴趣的是如何用纯粹的lambda演算表示不同的简单函数(即没有定义任何常量)。
我的一些讲义材料定义了布尔值,例如:
True = \ xy.x
错误 = \ xy.y
(\表示lambda符号)
如果将它们定义为这些选择器函数,则if条件可以很容易地定义为:
如果 = \ x.x
现在,我正在尝试为逻辑“和”函数提供一些简短形式。我的第一个猜测是:
和 = \ xy。{(如果 x)[(如果 y) True 错误] 错误}
所以基本上这个lambda函数会收到2个参数u v,其中两个都必须输入类似True / False。如果我使用逻辑表的所有4种组合进行各种beta减少,我会得到正确的结果。
然而,这个功能看起来有点难看,我正在考虑让它更优雅。这里有什么建议吗?
答案 0 :(得分:11)
我们可以减少你的答案以获得更精简的答案。
首先进行一些热身。显然IF x ==> x
,TRUE TRUE FALSE ==> TRUE
和FALSE TRUE FALSE ==> FALSE
如果x
是布尔值,那么x TRUE FALSE ==> x
。
现在我们减少
\x y . (IF x) ( (IF y) TRUE FALSE ) FALSE
\x y . x ( y TRUE FALSE ) FALSE -- using IF x ==> x
\x y . x ( y ) FALSE -- using y TRUE FALSE ==> y
\x y . x y FALSE -- clean up
这个表达式仍适用于真值表
AND TRUE TRUE = TRUE TRUE FALSE = TRUE
AND FALSE TRUE = FALSE TRUE FALSE = FALSE
AND TRUE FALSE = TRUE FALSE FALSE = FALSE
AND FALSE FALSE = FALSE FALSE FALSE = FALSE
答案 1 :(得分:4)
嗯,and True
是身份函数,而and False
是返回False
的常量函数,所以我们可以使用它。
and = \x. if x id (const False)
与
具有良好的对称性or = \x. if x (const True) id
(其中
id = \x. x
const = \x y. x
)
消除器的常见模式采用参数列表末尾的数据,这些数据通常可以优雅地使用无点样式,因此,如果您定义:
cond = \t f b. b t f
然后你可以表达
and = cond id (const False)
or = cond (const True) id
这是我得到的最好的。通过冷却方式观看bool,可能会有更优雅的配方。
答案 2 :(得分:3)
教会的布尔,对吗? :)我使用RankNTypes
功能开发了一个有趣的小模块,以便尽可能接近原始的Lambda演算版本。
因此,如果您启用RankNTypes
:
{-# LANGUAGE RankNTypes #-}
您可以将教会布尔值的类型表示为任何类型a -> a -> a
的函数a
,因此具有与您的非常相似的True和False的紧凑表示。这里的输入将允许我们更自由地编写函数。
type CBool = forall a. a -> a -> a
ctrue :: CBool
ctrue t f = t
cfalse :: CBool
cfalse t f = f
现在,用这些术语写的连词怎么样?假设你有一个左操作数l
和一个右操作数r
,它们都是CBool
,也就是函数a -> a -> a
,它们会返回第一个或第二个参数依赖无论是ctrue
还是cfalse
。您可以通过输入r
作为第一个参数并将l
本身作为第三个参数来评估此函数。如果l
为ctrue
,那么它将评估其第一个参数r
:如果它再次为ctrue
,那么我们的结合就会满足。在任何其他情况下,都会返回cfalse
。
cand :: CBool -> CBool -> CBool
cand l r = l r l
可以用类似的方式表示析取,使用直接评估表示输入中给出的布尔值的函数的相同技巧。除此之外,您将交换两个参数以评估l
:如果l
为ctrue
,则会返回l
本身,否则全部由r
决定的价值
cor :: CBool -> CBool -> CBool
cor l r = l l r
通过启用RankNTypes,我认为这是最接近的,因为你可以得到Lambda微积分中Church的布尔数的连词和析取的原始定义。我还编写了来自常规Bool和CBool来回翻译的函数,否定,以及具有相同风格的Church的自然数字。您可以在https://github.com/rtraverso86/haskkit/blob/master/Haskkit/Data/Church.hs找到完整的源代码。