简体   繁体   English

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

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

I can see how to write cons , cdr , car and other expressions in Racket using only lambda expressions (from SICP): 我可以看到如何使用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)))

Is there a way to write the equals predicate the same way? 有没有办法以相同的方式编写equals谓词?

I want to be able to compare defined expressions, which include numbers, but also compare arbitrary expressions which are not numbers. 我希望能够比较包含数字的已定义表达式,还可以比较不是数字的任意表达式。

I guess I am interested in developing mathematics from a minimal set of symbols. 我想我有兴趣从一组最小的符号开发数学。 From what I can understand, it will not be the same as developing math from Set Theory because the basics of Set Theory use the "is an element of" symbol and the null set symbol as its only non-logical symbols. 根据我的理解,它与从Set Theory开发数学不同,因为Set Theory的基础知识使用“是元素”符号而空集符号作为唯一的非逻辑符号。 If I understand correctly, the Lambda Calculus uses the "function" symbol (lambda) as its only necessary non-logical symbol. 如果我理解正确,Lambda Calculus使用“函数”符号(lambda)作为其唯一必要的非逻辑符号。 But, everything can be built from there. 但是,一切都可以从那里建立起来。 Is this correct? 这个对吗?

Equality of numbers can be done. 数字的平等可以做到。 I found this blog that had this and more: 我发现这个博客有这个以及更多:

(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

These are the print functions. 这些是打印功能。 These only gives you a more natural look for the values that really are just fine the way they are when passed to these, but just a little cryptic. 这些只会让你更自然地看到这些值,它们传递给它们的方式确实很好,但只是有点神秘。

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

cons , car , and cdr are a close-knit set of functions, very much isolated from the rest of the language; conscarcdr是一组紧密结合的功能,与其他语言非常隔离; you can implement them however you want with no real impact on anything else. 你可以实现它们,但不要对其他任何东西产生实际影响。

But = is a much more far-reaching function, whose implementation depends on the implementation of everything else in the language: you can't just rewrite it in isolation. 但是=是一个更为深远的功能,其实现取决于语言中其他所有内容的实现:您不能单独重写它。 Lambda calculus is Turing complete, so of course it is possible to implement = with just lambdas, but you have to structure the entirety of the language around it. Lambda演算是图灵完备的,因此当然可以用lambdas实现= ,但你必须围绕它构建整个语言。

One example implementation would involve requiring that each scheme-level value (assuming here that we're implementing scheme in terms of lambdas) is represented at the interpreter level as a cons, whose car is a number representing its type and whose cdr is a value of some sort. 一个示例实现将涉及要求每个方案级别的值(假设我们在lambdas方面实现方案)在解释器级别表示为cons,其car是表示其类型的数字,其cdr是值某种。 Then = could compare the types, and make some comparison of the values if the types match. 然后=可以比较类型,并在类型匹配时对值进行一些比较。

But now you have to dive into how you even represent numbers: okay, fine, Church numerals. 但现在你必须深入研究你如何表示数字:好吧,很好,教会的数字。 And how do you compare those for equality, in order to implement = ? 为了实现= ,你如何比较那些平等? All of this is possible, but it's a much more involved problem than reimplementing cons , car , and cdr . 所有这一切都是可能的,但这是一个比重新实现conscarcdr更复杂的问题。

I don't think that this can be done, in general -- in particular, because the function needs to deal with the type of both of its parameters, which can't be done with just a lambda . 我认为通常不会这样做 - 特别是因为函数需要处理它的两个参数的类型,而这只能用lambda来完成。

Really, the answer is "it depends." 真的,答案是“这取决于”。 Here, SCIP is implementing the lambda calculus in Racket. 在这里,SCIP正在实施Racket中的lambda演算。 Lambda calculus lists are different beasts than Racket lists -- they're closures, rather than a datatype. Lambda演算列表与Racket列表不同,它们是闭包,而不是数据类型。 cons , car and cdr , as defined here, are not compatible with the vanilla Racket language. 这里定义的conscarcdr与vanilla Racket语言不兼容。 If you want to use the lambda calculus, you're forced to implement all of it in your language. 如果你想使用lambda演算,你将被迫用你的语言实现所有这些。 In particular, you need to build Church numerals to put inside your lists and then define equality on them by following your favorite CS textbook . 特别是,您需要构建教会数字以放入列表中,然后通过关注您喜欢的CS教科书来定义它们的相等性。 ` `

You can't get the generalized equal? 你不能得到广义的equal? predicate, because this deals with much higher level constructs. 谓词,因为这涉及更高级别的结构。 Even if we restrict ourselves, equality soon becomes undecidable . 即使我们限制自己,平等也很快变得不可判定

Equivalence without equivalence functions or operators can use pattern matching and mapping. 没有等价函数或运算符的等价可以使用模式匹配和映射。 This is a sample and the regular expression matching emits #t when the first part of strings match. 这是一个示例,当字符串的第一部分匹配时,正则表达式匹配会发出#t。 "co" matches "cool" but not the reverse. “co”匹配“酷”而不是相反。 The matches here are only string and number. 这里的匹配只是字符串和数字。 Lists could easily be added. 列表很容易添加。 I think there might be a lambda/match function that will work like a regular lambda function that also does matching. 我认为可能有一个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