[英]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.