[英]How to write the equals predicate in Racket (or Scheme) using just lambda expressions
我可以看到如何使用lambda表达式(来自SICP)在Racket中编写cons
, cdr
, car
和其他表达式:
(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))
cons
, car
和cdr
是一组紧密结合的功能,与其他语言非常隔离; 你可以实现它们,但不要对其他任何东西产生实际影响。
但是=
是一个更为深远的功能,其实现取决于语言中其他所有内容的实现:您不能单独重写它。 Lambda演算是图灵完备的,因此当然可以用lambdas实现=
,但你必须围绕它构建整个语言。
一个示例实现将涉及要求每个方案级别的值(假设我们在lambdas方面实现方案)在解释器级别表示为cons,其car是表示其类型的数字,其cdr是值某种。 然后=
可以比较类型,并在类型匹配时对值进行一些比较。
但现在你必须深入研究你如何表示数字:好吧,很好,教会的数字。 为了实现=
,你如何比较那些平等? 所有这一切都是可能的,但这是一个比重新实现cons
, car
和cdr
更复杂的问题。
我认为通常不会这样做 - 特别是因为函数需要处理它的两个参数的类型,而这只能用lambda
来完成。
真的,答案是“这取决于”。 在这里,SCIP正在实施Racket中的lambda演算。 Lambda演算列表与Racket列表不同,它们是闭包,而不是数据类型。 这里定义的cons
, car
和cdr
与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.