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

时间:2014-06-06 20:37:50

标签: lambda scheme racket

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

(define (cons x y)
  (lambda (m) (m x y)))

(define (car z)
  (z (lambda (p q) p)))

(define (cdr z)
  (z (lambda (p q) q)))

有没有办法以相同的方式编写equals谓词?

我希望能够比较包含数字的已定义表达式,还能比较不是数字的任意表达式。

我想我有兴趣从最小的符号集开发数学。从我能理解的,它与从Set Theory开发数学不一样,因为Set Theory的基础使用"是"的一个元素。符号和空集符号作为其唯一的非逻辑符号。如果我理解正确,Lambda微积分使用"函数"符号(lambda)作为唯一必要的非逻辑符号。但是,一切都可以从那里建立起来。这是对的吗?

4 个答案:

答案 0 :(得分:1)

可以完成数字的平等。我发现this blog有这个以及更多:

(define (zero  f) (λ (x) x))
(define (succ  n) (λ (f) (λ (x) (f ((n f) x)))))
(define one   (succ zero))
(define two   (succ one)) ; continue to define all numbers
(define (add a b) ((b succ) a))

;; here we use you definition of cons, car, cdr
(define (pred n) 
  (cdr ((n (λ (p) 
             (cons (succ (car p)) (car p)))) 
        (cons zero zero))))

(define (if c a b) (c a b))
(define (true a b) a)
(define (false a b) b)
(define (zero? n) ((n (λ (x) false)) true))
(define (sub a b) ((b pred) a))
(define (mult a b) ((a (λ (x) (add x b))) zero))

;; here is numeric compare
(define (= a b) (zero? (sub a b)))

(print-boolean (= (add two two) (mult two two))) ; ==> true    
(print (add two two)) ; ==> 4

这些是打印功能。这些只会让你更自然地看到那些传递给它们的方式非常好的值,但只是有点神秘。

(define (print n) ((n (λ (n) (+ n 1))) 0))
(define (print-boolean n) (n 'true 'false))

答案 1 :(得分:0)

conscarcdr是一组紧密结合的功能,与语言的其他部分非常隔离;你可以按照自己的意愿实施它们,而不会对其他任何事情产生实际影响。

但是=是一个更为深远的功能,其实现取决于语言中其他所有内容的实现:您不能孤立地重写它。 Lambda演算是Turing完成的,所以当然可以用lambdas实现=,但是你必须围绕它构建整个语言。

一个示例实现将涉及要求每个方案级别的值(假设我们在lambda中实现方案)在解释器级别表示为cons,其car是表示其类型的数字和其cdr是某种值。然后=可以比较类型,并在类型匹配时对值进行一些比较。

但现在你必须深入研究你如何表示数字:好吧,很好,教会数字。为了实现=,你如何比较那些平等?所有这一切都是可能的,但与重新实现conscarcdr相比,这是一个更复杂的问题。

答案 2 :(得分:0)

我认为通常不会这样做 - 特别是因为函数需要处理其两个参数的类型,而这只能通过lambda来完成。

真的,答案是“这取决于”。在这里,SCIP正在实施Racket中的lambda演算。 Lambda演算列表与Racket列表不同,它们是闭包,而不是数据类型。此处定义的conscarcdr与vanilla Racket语言不兼容。如果你想使用lambda演算,你将被迫用你的语言实现所有这些。特别是,您需要构建Church numerals以放入列表中,然后按照your favorite CS textbook定义它们的相等性。 `

您无法获得广义equal?谓词,因为它可以处理更高级别的结构。 Even if we restrict ourselves, equality soon becomes undecidable

答案 3 :(得分:0)

没有等价函数或运算符的等价可以使用模式匹配和映射。这是一个示例,当字符串的第一部分匹配时,正则表达式匹配会发出#t。 " CO"匹配"酷"但不是相反。这里的匹配只是字符串和数字。列表很容易添加。我认为可能有一个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)])