我正在尝试撤销计划中的列表,我想出了以下解决方案:
(define l (list 1 2 3 4))
(define (reverse lista)
(car (cons (reverse (cdr (cons 0 lista))) 0)))
(display (reverse l))
虽然它有效但我真的不明白为什么会有效。
在我的脑海里,它将评估一系列嵌套的缺点,直到()(带有一个元素的列表的cdr)的cons(。)
我想我不理解替代模型,有人可以解释一下它的工作原理吗?
Obs:
它应该只在非嵌套列表中起作用。
采取SICP形式,练习2.18。
我知道有很多类似的问题,但据我所见,没有人提出过 这个解决方案。
谢谢
答案 0 :(得分:1)
这与其他语言的解决方案几乎完全相同:
现在......根据我对LISP日的理解,代码看起来更像是这样:
(append (reverse (cdr lista)) (list (car lista)))
...符合我上面的描述。
答案 1 :(得分:1)
[因为这种情况经常发生,我总是写下答案]
Scheme实现确实有内置版本的reverse,map,append等,因为它们在RxRS中指定(例如https://www.cs.indiana.edu/scheme-repository/R4RS/r4rs_8.html)。
在学习计划(实际上是任何lisp方言)的过程中,无论如何实施它们确实很有价值。危险的是,一个人的定义可能与内置的一个碰撞(尽管例如方案的定义或者lisp的标签应该遮蔽它们)。因此,总是值得用其他名称来称呼这个手工制作的实现,比如“my-reverse”,“my-append”等。这样你就可以省去很多困惑,如下所示:
(let ([append
(lambda (xs ys)
(if (null? xs)
ys
(cons (car xs) (append (cdr xs) ys))))])
(append '(hello) '(there!)))
- 这个似乎可以正常工作,创建一个错误的印象,“let”的工作方式与“letrec”相同。但只是将名称更改为“my-append”并且它会中断,因为在评估lambda表单时,符号“my-append”尚未绑定到任何内容(不像“append”,它被定义为内置过程) )。
当然这样的表单将使用动态作用域的语言,但是scheme是词法(除了“define”s),原因是引用透明度(但是到目前为止,我只能引用感兴趣的offtopic)读者阅读其中一篇lambda论文http://repository.readscheme.org/ftp/papers/ai-lab-pubs/AIM-453.pdf)。
答案 2 :(得分:0)
有几种方法可以做到这一点。这是另一个:
(define my-reverse
(lambda (lst)
(define helper
(lambda (lst result)
(if (null? lst)
result
(helper (cdr lst) (cons (car lst) result)))))
(helper lst '())))