Scheme 方案可变函数

Scheme 方案可变函数,scheme,racket,r5rs,Scheme,Racket,R5rs,在过去的几个月里,我一直在自学R5RS方案,并且刚刚开始学习可变函数。我做过两个类似的函数,但似乎发现了我的错误 (define (lst-functions) (let ((lst '())) (define (sum lst) (cond ((null? lst) 0) (else (+ (car lst) (sum (cdr lst)))))) (define (length? lst)

在过去的几个月里,我一直在自学R5RS方案,并且刚刚开始学习可变函数。我做过两个类似的函数,但似乎发现了我的错误

(define (lst-functions)
  (let ((lst '()))
    (define (sum lst)     
      (cond ((null? lst) 0)
            (else
             (+ (car lst) (sum (cdr lst))))))
    (define (length? lst)
      (cond ((null? lst) 0)
            (else
             (+ 1 (length? (cdr lst))))))
    (define (average)
      (/ (sum lst) (length? lst)))
    (define (insert x)
      (set! lst (cons x lst)))
    (lambda (function)
      (cond ((eq? function 'sum) sum)
            ((eq? function 'length) length?)
            ((eq? function 'average) average)
            ((eq? function 'insert) insert)
            (else
             'undefined)))))

(define func (lst-functions))
((func 'insert) 2)
((func 'average))

有些函数是递归的,但定义时没有参数。因此
(sum(cdrlst))
不应该工作,因为
sum
使用
lst
。您可以通过定义辅助对象来完成此操作:

(define (sum-rec lst)
  (if (null? lst)
      0
      (+ (car lst) (sum-rec (cdr lst)))))
或者使用累加器:

(define (sum-iter lst acc)
  (if (null? lst)
      acc
      (sum-iter (cdr lst) (+ (car lst) acc)))
您的
sum
当然会使用它传递
lst

(define (sum)
  (sum-iter lst 0))
或者,您可以让驱动程序部分应用它们,如下所示:

(lambda (function)
      (cond ((eq? function 'sum) (lambda () (sum-iter lst))
            ...))

旁注<代码>长度?是一个命名奇怪的函数。名称末尾的问号通常是为返回真值或假值的函数保留的,这显然会返回一个数字

您不是在使用它的过程中声明
lst
参数,而是在调用它们时传递它。我标记了已修改的行,请尝试以下操作:

(define (lst-functions)
  (let ((lst '()))
    (define (sum lst)     ; modified
      (cond ((null? lst) 0)
            (else
             (+ (car lst) (sum (cdr lst))))))
    (define (length? lst) ; modified
      (cond ((null? lst) 0)
            (else
             (+ 1 (length? (cdr lst))))))
    (define (average)
      (/ (sum lst) (length? lst)))
    (define (insert x)
      (set! lst (cons x lst)))
    (lambda (function)
      (cond ((eq? function 'sum) (lambda () (sum lst)))        ; modified
            ((eq? function 'length) (lambda () (length? lst))) ; modified
            ((eq? function 'average) average)
            ((eq? function 'insert) insert)
            (else
             'undefined)))))
现在它如预期的那样工作:

(define func (lst-functions))
((func 'insert) 2)

((func 'average)) 
=> 2
((func 'sum))
=> 2
((func 'length))
=> 1

谢谢你的长度提示?我不想使用内置的length函数,这就是为什么会有一个?。我会记住这个事实。