因此,从 SICP ,我们知道cons
car
和cdr
可以定义为一个过程:
(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)))
但是预定义的过程list
使用原始的cons
来获取构建列表的参数。这意味着,list
构建的列表不是我想要的过程。
(car (list 1 2 3))
;The Object (1 2 3) is not applicable
所以我写这个:
(define (list . l)
(if (null? l)
'()
(cons (original-car l)
(list (original-cdr l)))))
我只是想知道如何定义original-car
和original-cdr
。有没有办法在Scheme中复制一个过程?或者有一些替代方法来解决这个问题。 THX
答案 0 :(得分:4)
如果在重新定义之前需要保存对“原始”程序的引用,只需在定义“新”程序之前创建一个别名(我想这就是“复制”它们的意思)。像这样:
(define original-cons cons)
(define original-car car)
(define original-cdr cdr)
(define original-list list)
通过这种方式,只要我们用新名称引用旧程序,它们仍然可以使用。换句话说,cons
,car
,cdr
和list
作为程序的实现将如下所示:
(define (my-cons x y)
(lambda (m) (m x y)))
(define (my-car z)
(z (lambda (p q) p)))
(define (my-cdr z)
(z (lambda (p q) q)))
(define (my-list . els)
(if (null? els)
'()
(my-cons
(original-car els)
(apply my-list (original-cdr els)))))
果然,它有效:
(define lst (my-list 1 2 3 4))
lst
=> #<procedure>
(my-car lst)
=> 1
(my-car (my-cdr lst))
=> 2
答案 1 :(得分:2)
实现中的列表定义为
(define (list . l) l)
但是,这是使用了很多底层实现。例如。工作它使用原生的利弊。 cons
中定义的SICP
是一个思想实验,因此您的实施需要稍微纠正:
(define (my-cons x y)
(lambda (m) (m x y)))
(define (my-car z)
(z (lambda (p q) p)))
(define (my-cdr z)
(z (lambda (p q) q)))
(define (my-list . l)
(define (my-list-aux l)
(if (null? l)
'()
(my-cons (car l)
(my-list-aux (cdr l)))))
(my-list-aux l))
;; optional, update binding
(define car my-car)
(define cdr my-cdr)
(define list my-list)
my-cons my-car,my-cdr和my-list是你问题中定义的。只有更改才能引用正确的程序(名称与Scheme不冲突)