SCHEME 可变函数
SCHEME Mutable Functions
在过去的几个月里,我一直在自学 Scheme 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 (cdr lst))
不应该工作,因为 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))
...))
旁注。 length?
是一个奇怪的命名函数。名称末尾的问号通常保留给 return 真值或假值的函数,这显然是 return 一个数字。
您没有在使用它的过程中声明 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
在过去的几个月里,我一直在自学 Scheme 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 (cdr lst))
不应该工作,因为 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))
...))
旁注。 length?
是一个奇怪的命名函数。名称末尾的问号通常保留给 return 真值或假值的函数,这显然是 return 一个数字。
您没有在使用它的过程中声明 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