通过参数计划递归

Scheme Recursion Through Arguments

我是 Scheme 的新手,这是一道作业题,所以请不要直接回答。

这是我的问题:

Write a recursive procedure (any? arg1 arg2 ...), where the argi's are boolean values. any? returns #t if any of its arguments is #t, and #f otherwise.

这些是限制条件:

You may not use the built-in procedures map, apply, list->vector, or vector->list in any procedure. Likewise, do not use a let expression or an internal define expression in any procedure, unless the problem says otherwise.

这是我的代码:::

(define any?
  (lambda args
    (if (null? args)
        #f
        (if (equal? #t (car args))
            #t
            (any? (cdr args))))))

我的问题似乎是我在最后一行遇到了无限循环(任何?(cdr args))。我不确定为什么会这样。我的教授说暗示是要写什么?作为接口过程,并编写一个处理列表的助手。我不确定这会有什么帮助。

如有任何建议,我们将不胜感激!

编辑:我添加了新代码。我仍然遇到无限循环。

(define any?
  (lambda args
    (any-helper args)))

(define any-helper
  (lambda (list)
    (if (null? list)
        #f
        (if (equal? #t (car list))
            #t
            (any? (cdr list))))))

我想通过在我的主函数中编写 lambda args,我会向我的辅助函数传递一个列表。我不确定这是否真的发生了。我不确定如何确保我不会无限递归 '() 。

考虑函数应用程序 (any? #f) 采取的步骤。这导致对 (any? '()) 的递归调用。接下来,它检查此调用中的参数列表 '(()) 是否为 null?(它不是,因为它是一个包含 '() 的列表)。 (equal #t '(()) 也是假的,所以它会一直递归,因为你用相同数量的参数调用它,而不是在每次递归调用中减少输入的大小。

嘿,这是我的第 100 个回答!

当你有一个符号参数或一个虚线列表作为原型时,最后一个参数,在你的情况下 args,包含给定操作数的其余部分。

假设您评估 (any? #f 5 6),那么 args 将是 (#f 5 6)。由于第一个参数是 #f,因此您调用 (any? '(5 6)) 而不是 (any? 5 6)

通常你会创建一个命名的 let 或一个本地过程来处理一个参数列表,这样你的代码才能真正工作,但由于你不允许这样做,你需要使用 apply改为这样做。

(apply any? '(#f 5 6)) 等同于 (any? #f 5 6)。您可以将 apply 视为过程定义中带点的 list/symbol 原型的对立面。

PS:如果使用 any-helper 而不是 any? 进行递归,则使用 any-helper 的更新将完美运行。