纯Lambda微积分 - 和功能

时间:2014-06-30 23:18:19

标签: haskell functional-programming lambda-calculus

我目前正在学习Haskell,还参加了一个关于大学函数式编程的理论讲座。

我知道这纯粹是理论/学术问题,但我感兴趣的是如何用纯粹的lambda演算表示不同的简单函数(即没有定义任何常量)。

我的一些讲义材料定义了布尔值,例如:

  

True = \ xy.x
  错误 = \ xy.y

(\表示lambda符号)

如果将它们定义为这些选择器函数,则if条件可以很容易地定义为:

  

如果 = \ x.x

现在,我正在尝试为逻辑“和”函数提供一些简短形式。我的第一个猜测是:

  

= \ xy。{(如果 x)[(如果 y) True 错误] 错误}

所以基本上这个lambda函数会收到2个参数u v,其中两个都必须输入类似True / False。如果我使用逻辑表的所有4种组合进行各种beta减少,我会得到正确的结果。

然而,这个功能看起来有点难看,我正在考虑让它更优雅。这里有什么建议吗?

3 个答案:

答案 0 :(得分:11)

我们可以减少你的答案以获得更精简的答案。

首先进行一些热身。显然IF x ==> xTRUE TRUE FALSE ==> TRUEFALSE 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本身作为第三个参数来评估此函数。如果lctrue,那么它将评估其第一个参数r:如果它再次为ctrue,那么我们的结合就会满足。在任何其他情况下,都会返回cfalse

cand :: CBool -> CBool -> CBool
cand l r = l r l

可以用类似的方式表示析取,使用直接评估表示输入中给出的布尔值的函数的相同技巧。除此之外,您将交换两个参数以评估l:如果lctrue,则会返回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找到完整的源代码。