我现在正在学习SICP,并执行EX2.23我已经为以下代码而努力:

(define (for-each proc items)
   (if (null? items)
       #t
       ((proc (car items))
        (for-each proc (cdr items)))))

但运行时,出现错误: 程序申请:预期程序,给定:#;论据是:()

我想我知道原因:我递归地调用 for-each 函数,每个调用的 for-each 都想要返回值

但是当我修改了代码后:

(define (for-each proc items)
  (cond ((null? items) #t)
        (else (proc (car items)) (for-each proc (cdr items)))))

它运行良好。我不明白,为什么?在 条件, ,每个调用for-each都不需要返回值吗?

我使用了 DrScheme,并选择语言 SICP

我的母语不是英语,所以如果有什么没有描述清楚的地方,请告诉我

有帮助吗?

解决方案

但运行时,出现错误:程序申请:预期 > 程序,给定:#;论据是:()

我想我知道原因:我递归地调用 for-each 函数,> 每个调用的 for-each 都想要返回值

不,这是因为在替代条款中 if 你有这个组合 ((proc (car items)) (for-each proc (cdr items))). 。您打算评估这两种组合 (proc (car items))(for-each proc (cdr items)) 顺序地,为此你认为将它们放在另一对括号中会起作用。但实际上,您指定的是结果 (proc (car items)) 是一个应用于参数的过程,该参数是以下参数的返回值 (for-each proc (cdr items)). 。情况并非如此,并且您会收到错误。关键是Lisp中的括号不是为了分组,而是有一定的意义。

问题是 if 该位置只能有一个组合,而您希望连续有两个组合。另一方面, cond 不受此类限制;您可以将尽可能长的单个组合序列放入一个的后续部分 cond 条款如您所愿。这种情况就是语言被定义为如何工作的。

你也可以使用 cond 在这些情况下,但如果您仍然想使用 if 有一些选项可以将多种组合填充到一个组合中。E.G。您可以创建一个 lambda 过程,其主体是这两个组合并立即将其关闭:

(define (for-each proc items)
   (if (null? items)
       #t
       ((lambda ()
          (proc (car items))
          (for-each proc (cdr items)) )) ))

或者你可以使用 begin 这实际上是用于这样的目的:

(define (for-each proc items)
   (if (null? items)
       #t
       (begin
          (proc (car items))
          (for-each proc (cdr items)) ) ))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top