scheme - 在 Scheme 中检索列表的第 n 个 cdr
问题描述
我想返回列表的第 n 个 cdr。例如,我说
(nth-cdr 3 '(a b c d e))
我会得到(c d e)
输出。我不确定我的代码哪里出错了。
我的做法是这样的。我会检查是否(= num 0)
是,我会返回列表。如果没有,我将递归调用并从andnth-cdr
中减去 1num
cdr list
代码是这样的
(define arbitrary-cdr (lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list))
)))
但是,当我尝试执行此操作时出现此错误(arbitrary-cdr 3 ‘(a b c d e))
‘: undefined;
cannot reference an identifier before its definition
我不确定这意味着什么。当我这么说时,这意味着我达到了基本情况并且只想返回列表。我认为我的逻辑是正确的。
解决方案
您发布的第一个代码是:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
(list)
(arbitrary-cdr (- num 1) (cdr list)))))
您收到的错误是:
scratch.rkt> (arbitrary-cdr 3 '(a b d c e))
; application: not a procedure;
; expected a procedure that can be applied to arguments
; given: '(c e)
问题是您用作过程list
的参数arbitrary-cdr
;由于 Racket 是一个 lisp-1,程序没有自己的命名空间,所以重新定义了list
. 使用(list)
和list
重新定义的代码试图调用((c e))
,但(c e)
不是过程。
这是一个很好的例子,说明了为什么您不应该在Scheme 或 Racket 中自己的过程定义中使用list
或其他内置过程标识符作为参数。你可以在 Common Lisp 中解决这个问题,因为 Common Lisp 是一个 lisp-2,即有一个单独的函数命名空间。
使用您更新的代码:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list)))))
我没有收到您报告的错误;也许您的代码与您发布的代码不完全一样。但是,您的代码逻辑存在错误。实际上,将始终返回一个空列表:
scratch.rkt> (arbitrary-cdr 3 '(a b c d e f))
'()
问题是当达到基本情况时,您应该返回输入列表,而不是空列表。也就是说,给定(arbitrary-cdr 0 '(a b c))
,您希望结果是(a b c)
。这也意味着你的测试用例是错误的;(arbitrary-cdr 0 '(a b c d e))
-->'(a b c d e)
和(arbitrary-cdr 3 '(a b c d e))
--> '(d e)
。
这是您重写的代码,使用xs
而不是list
避免重新定义,并xs
在达到基本情况时返回而不是空列表:
(define arbitrary-cdr
(lambda (num xs)
(if (= num 0)
xs
(arbitrary-cdr (- num 1) (cdr xs)))))
示例交互:
scratch.rkt> (arbitrary-cdr 0 '(a b c d e))
'(a b c d e)
scratch.rkt> (arbitrary-cdr 1 '(a b c d e))
'(b c d e)
scratch.rkt> (arbitrary-cdr 3 '(a b c d e))
'(d e)
推荐阅读
- scala - 具有依赖注入的数据库操作的可重用代码
- java - 如何使 java App 成为 Windows 上的默认邮件客户端?
- python - 用熊猫滚动标准差绘制正态分布?
- python - 如何在 Django 中创建随机 slug
- react-native - React Native Android launchMode singleTask getLaunchOptions 不再被调用
- javascript - 如何使用 jquery 读取已使用 html 表单上传的文件 csv?
- flutter - 访问地图内的列表
- swiftui - SwiftUI:有一个按钮自己改变吗?
- c++ - 在 mac 上编译 hello world wxWidget 程序时找不到“wx/wx.h”文件
- spring-boot - SpringBoot 将参数传递给 CommandLineRunner