我正在 DrRacket 上调试此代码:
#lang racket
(define last-element-on-list
(lambda l
(cond ((null? l) '())
((null? (cdr l)) (car l))
(else (last-element-on-list (cdr l)))
)
)
)
(define lst '(
(n 25 f +)
(s 25 m +)
(ll 20 no -)))
(list-ref lst 0)
(last-element-on-list (list-ref lst 0))
代码(list-ref lst 0)
返回'(n 25 f +)
,但是当我进入过程last-element-on -list
参数l
的值为((n 25 f +))
。
为什么l
是过程last-element-on-list
中的列表的列表?
最佳答案
(lambda (x) ...)
形式和 (lambda x ...)
形式之间存在差异。
观察这两个示例之间的区别:
;; Example 1.
(define f
(lambda (x)
(if (list? x)
(display "x is a list!")
(display "x is not a list"))))
(f 1) ; Displays "x is not a list".
;; Example 2.
(define g
(lambda x
(if (list? x)
(display "x is a list!")
(display "x is not a list"))))
(g 1) ; Displays "x is a list!".
(lambda x ...)
形式允许 lambda 接受任意数量的参数,所有参数都放入绑定(bind)到 lambda 中的 x
的列表中 body 。即 x
是参数列表。
这就是为什么当您给 g
一个列表(例如 (g '(1 2 3))
)时,x
将是 '((1 2 3))
(列表列表)。
要修复您的代码:
(define last-element-on-list
(lambda (l) ; <- ATTENTION.
(cond ((null? l) '()) ; FIXME: raise error instead.
((null? (cdr l)) (car l))
(else (last-element-on-list (cdr l))))))
您可以在The Racket Guide中阅读有关lambda
的更多信息。 。特别是,请查看第 4.4.1 节(声明剩余参数)。
关于传递给过程的列表转换为过程内列表的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53159405/