如何在Racket中判断函数相等及验证列表中的加号标识符
Hey there, let's break down your two Racket questions clearly:
First, it's important to understand that Racket treats functions as first-class objects, but standard equality checks like eq?, eqv?, or equal? won’t work for most separate function definitions or anonymous functions with identical behavior. These checks compare the function’s memory identity, not its implementation or behavior.
For example:
(define add1 (lambda (x) (+ x 1))) (define another-add1 (lambda (x) (+ x 1))) (eq? add1 another-add1) ; Returns #f (equal? add1 another-add1) ; Also returns #f
To compare functions by their implementation and captured closure values, use procedure-equal? from the racket/procedure library. This function checks if two procedures have matching code structures and if any captured variables are equal.
Here’s how to use it:
(require racket/procedure) (define add1 (lambda (x) (+ x 1))) (define another-add1 (lambda (x) (+ x 1))) (procedure-equal? add1 another-add1) ; Returns #t
A quick note about closures: if your functions capture variables, procedure-equal? will only return #t if those captured values are also equal. For example:
(define a 5) (define func-a (lambda (x) (+ x a))) (define b 5) (define func-b (lambda (x) (+ x b))) (procedure-equal? func-a func-b) ; #t, since a and b have the same value (define c 6) (define func-c (lambda (x) (+ x c))) (procedure-equal? func-a func-c) ; #f, since 5 != 6
+ is indeed the addition operator when traversing lists like '((a + b) + (c + d))? When working with a list like '((a + b) + (c + d)), the + here is a symbol (not a function directly). You have two common approaches depending on your needs:
Option 1: Check the symbol name directly
If you only need to confirm the identifier’s name is + (regardless of what the symbol is bound to), compare it directly to the symbol '+:
(define expr '((a + b) + (c + d))) ; Example traversal to check operators (for-each (lambda (elem) (cond [(list? elem) (let ((op (second elem))) (if (eq? op '+) (displayln "Found the plus operator (by symbol)") (displayln "Not the plus operator")))] [(eq? elem '+) (displayln "Found the plus operator (top-level)")])) expr)
Option 2: Verify the symbol maps to the real addition function
If you need to ensure the symbol + binds to Racket’s built-in addition function (in case someone redefined + locally), compare the resolved function to the original + operator from racket/base:
(require racket/base) ; Helper function to check if the symbol points to genuine addition (define (genuine-plus? op-symbol) (eq? (eval op-symbol) racket/base:+)) (genuine-plus? '+) ; #t in normal environments (genuine-plus? '*) ; #f
This works even if + is redefined locally—for example, if someone does (define + *), genuine-plus? '+ will return #f, since the local + now maps to multiplication instead of the original addition function.
内容的提问来源于stack exchange,提问作者Will




