我可以看到如何仅使用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微积分使用"函数"符号(lambda)作为唯一必要的非逻辑符号。但是,一切都可以从那里建立起来。这是对的吗?
答案 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)
cons
,car
和cdr
是一组紧密结合的功能,与语言的其他部分非常隔离;你可以按照自己的意愿实施它们,而不会对其他任何事情产生实际影响。
但是=
是一个更为深远的功能,其实现取决于语言中其他所有内容的实现:您不能孤立地重写它。 Lambda演算是Turing完成的,所以当然可以用lambdas实现=
,但是你必须围绕它构建整个语言。
一个示例实现将涉及要求每个方案级别的值(假设我们在lambda中实现方案)在解释器级别表示为cons,其car是表示其类型的数字和其cdr是某种值。然后=
可以比较类型,并在类型匹配时对值进行一些比较。
但现在你必须深入研究你如何表示数字:好吧,很好,教会数字。为了实现=
,你如何比较那些平等?所有这一切都是可能的,但与重新实现cons
,car
和cdr
相比,这是一个更复杂的问题。
答案 2 :(得分:0)
我认为通常不会这样做 - 特别是因为函数需要处理其两个参数的类型,而这只能通过lambda
来完成。
真的,答案是“这取决于”。在这里,SCIP正在实施Racket中的lambda演算。 Lambda演算列表与Racket列表不同,它们是闭包,而不是数据类型。此处定义的cons
,car
和cdr
与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)])