4

我现在正在学习 sicp 并执行 ex2.23 我编写了以下代码:

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

但是运行时,会报错:procedure application: expected procedure, given: #; 论据是:()

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

但是当我修改了代码时:

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

它运行良好。我不明白,为什么?在cond中,是否每个调用的每个都不需要返回值?

我使用 DrScheme,并选择语言SICP

我不是以英语为母语的人,所以如果有没有描述清楚的东西,请告诉我

4

1 回答 1

8

但是运行时,会报错:procedure application: expected > procedure, given: #; 论据是:()

我想我知道原因:我递归调用 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,可以使用一些选项将多个组合塞进一个中。例如。您可以创建一个 lambda 过程,其主体是两种组合并立即将其关闭:

(定义(针对每个 proc 项目)
   (如果(空?项目)
       #t
       ((拉姆达()
          (过程(汽车物品))
          (for-each proc (cdr items)) )) ))

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

(定义(针对每个 proc 项目)
   (如果(空?项目)
       #t
       (开始
          (过程(汽车物品))
          (for-each proc (cdr items)) ) ))
于 2009-11-24T05:17:04.383 回答