繁体   English   中英

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

[英]How to write the equals predicate in Racket (or Scheme) using just lambda expressions

我可以看到如何使用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 Calculus使用“函数”符号(lambda)作为其唯一必要的非逻辑符号。 但是,一切都可以从那里建立起来。 这个对吗?

数字的平等可以做到。 我发现这个博客有这个以及更多:

(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))

conscarcdr是一组紧密结合的功能,与其他语言非常隔离; 你可以实现它们,但不要对其他任何东西产生实际影响。

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

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

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

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

真的,答案是“这取决于”。 在这里,SCIP正在实施Racket中的lambda演算。 Lambda演算列表与Racket列表不同,它们是闭包,而不是数据类型。 这里定义的conscarcdr与vanilla Racket语言不兼容。 如果你想使用lambda演算,你将被迫用你的语言实现所有这些。 特别是,您需要构建教会数字以放入列表中,然后通过关注您喜欢的CS教科书来定义它们的相等性。 `

你不能得到广义的equal? 谓词,因为这涉及更高级别的结构。 即使我们限制自己,平等也很快变得不可判定

没有等价函数或运算符的等价可以使用模式匹配和映射。 这是一个示例,当字符串的第一部分匹配时,正则表达式匹配会发出#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)])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM