如何仅使用lambda表达式在Racket(或Scheme)中编写equals谓词

如何仅使用lambda表达式在Racket(或Scheme)中编写equals谓词,lambda,scheme,racket,Lambda,Scheme,Racket,我可以看到如何仅使用lambda表达式(来自SICP)在Racket中编写cons、cdr、car和其他表达式: 有没有一种方法可以用同样的方法写出equals谓词 我希望能够比较定义的表达式,其中包括数字,但也比较非数字的任意表达式 我想我对从一组最小的符号发展数学感兴趣。据我所知,这与从集合论发展数学不同,因为集合论的基础使用“是元素”符号和空集合符号作为其唯一的非逻辑符号。如果我理解正确,Lambda演算使用“函数”符号(Lambda)作为其唯一必要的非逻辑符号。但是,一切都可以从那里建造

我可以看到如何仅使用lambda表达式(来自SICP)在Racket中编写
cons
cdr
car
和其他表达式:

有没有一种方法可以用同样的方法写出equals谓词

我希望能够比较定义的表达式,其中包括数字,但也比较非数字的任意表达式


我想我对从一组最小的符号发展数学感兴趣。据我所知,这与从集合论发展数学不同,因为集合论的基础使用“是元素”符号和空集合符号作为其唯一的非逻辑符号。如果我理解正确,Lambda演算使用“函数”符号(Lambda)作为其唯一必要的非逻辑符号。但是,一切都可以从那里建造。这是正确的吗?

cons
car
cdr
是一组紧密结合的函数,与语言的其他部分非常隔离;您可以按照自己的意愿实现它们,而不会对其他任何事情产生实际影响

但是
=
是一个影响深远得多的函数,它的实现取决于语言中其他所有内容的实现:您不能孤立地重写它。Lambda演算是图灵完备的,因此当然可以只使用Lambda实现
=
,但是您必须围绕它构建整个语言

一个示例实现将要求每个方案级别的值(假设我们在这里根据lambdas实现方案)在解释器级别表示为cons,cons的car是表示其类型的数字,cdr是某种类型的值。然后,
=
可以比较类型,如果类型匹配,则对值进行一些比较


但现在你必须深入研究你是如何表示数字的:好吧,好吧,教堂数字。为了实现
=
,您如何比较这些等式?所有这些都是可能的,但这是一个比重新实现
cons
car
cdr
更复杂的问题,一般来说,我认为这是不可能做到的——特别是,因为函数需要处理两个参数的类型,而这不能用
lambda
来完成

实际上,答案是“视情况而定”。在这里,SCIP正在Racket中实现lambda演算。Lambda演算列表与Racket列表不同——它们是闭包,而不是数据类型<此处定义的code>cons、
car
cdr
与普通球拍语言不兼容。如果你想使用lambda演算,你必须在你的语言中实现它。特别是,您需要构建以放入列表中,然后通过以下方式定义它们的相等性`


您无法得到广义的
equal?
谓词,因为它处理更高级别的构造

可以实现数字相等。我发现有这样或更多:

(定义(零f)(λ(x)x))
(定义(连续n)(λ(f)(λ(x)(f((nf)x‘‘)’))
(定义一(成功零))
(定义两个(成功一个));继续定义所有数字
(定义(添加a b)((b such)a))
;; 这里我们使用cons,car,cdr的定义
(定义(pred n)
(cdr((n(λ)(p)
(cons(suc(car p))(car p)))
(反对者零零)
(定义(如果是c a b)(c a b))
(定义(真实的a b)a)
(定义(假a b)b)
(定义(零?n)((n(λ(x)假))真))
(定义(子a b)((b pred)a))
(定义(mult a b)((a(λ(x)(加x b)))零)
;; 这里是数字比较
(定义(=ab)(零(子ab)))
(打印布尔值(=(加两个二)(多个二个二));=>真的
(打印(添加两个));=>4.
这些是打印功能。这些只会让您更自然地看到值,这些值在传递给这些值时与它们的方式一样,但有点神秘

(定义(打印n)((n(λ(n)(+n1)))0))
(定义(打印布尔值n)(n'true'false))

没有等价函数或运算符的等价可以使用模式匹配和映射。这是一个示例,当字符串的第一部分匹配时,正则表达式匹配将发出#t。“co”与“cool”匹配,但不是相反。这里的匹配项只有字符串和数字。可以很容易地添加列表。我认为可能会有一个lambda/match函数,它的工作方式类似于也进行匹配的常规lambda函数

(define/match (equ? a b)
  [( (? number? a) (? number? b) )
     (case (- a b) [(0) #t] [else #f])]
  [( (? string? a) (? string? b) ) 
     (if (regexp-match? (regexp-quote a) b) #t #f)])

与球拍或球拍的兼容性非常重要。但是值得注意的是,使用闭包可以实现cons、car和cdr,它们的行为方式与“内置”的行为方式无法区分(当然,除了不能同时使用这两个)。它们是兼容的,因为任何只使用其中一个的代码都可以与另一个很好地协同工作。
null?
predicate?@WillNess我的答案只涉及数字。它是
car
,因为
nil
被定义为
(cons true true)
。这意味着true不能是列表中的元素。
(define/match (equ? a b)
  [( (? number? a) (? number? b) )
     (case (- a b) [(0) #t] [else #f])]
  [( (? string? a) (? string? b) ) 
     (if (regexp-match? (regexp-quote a) b) #t #f)])