(define generalized-triangular
(lambda (input n)
(if (= n 1)
1
(+ (input n) (generalized-triangular (- n 1))))))
该程序旨在将数字和函数作为输入并执行以下操作。
f(1) + f(2) + f(3)+ … + f(N).
示例输入为:
(generalized-triangular square 3)
错误消息:
if: bad syntax;
has 4 parts after keyword in: (if (= n 1) 1 (+ (input n) (generalized-triangular (- n 1))) input)
错误非常明确 - if
形式在条件之后只能有两个部分 - 结果(如果条件为真)和替代(如果条件为假)。也许你的意思是这个?
(if (= n 1)
1
(+ (input n) (generalized-triangular input (- n 1))))
我将input
从原始代码中移开,它位于错误的位置,因为对generalized-triangular
的调用期望两个参数,顺序正确。
记录:如果您需要在结果或替代中执行多个表达式(您的问题不是这种情况,但了解它很有用),那么您必须将它们打包在一个begin
中,例如:
(if <condition> ; condition
(begin ; consequent
<expression1>
<expression2>)
(begin ; alternative
<expression3>
<expression4>))
或者,您可以使用 cond
,它有一个隐式begin
:
(cond (<condition> ; condition
<expression1> ; consequent
<expression2>)
(else ; alternative
<expression3>
<expression4>))
字面答案
您在问题中发布的代码很好:
(define generalized-triangular
(lambda (input n)
(if (= n 1)
1
(+ (input n) (generalized-triangular (- n 1))))))
您问题中的错误消息将针对以下代码:
(define generalized-triangular
(lambda (input n)
(if (= n 1)
1
(+ (input n) (generalized-triangular (- n 1)))
input)))
问题是input
. if
的形式是(if <cond> <then> <else>)
.不算if
本身,它有 3 个部分。上面的代码提供 4.
真正的答案
两个提示:
使用 DrRacket 编写代码,让它帮助您进行缩进。我无法理解您的原始代码。(即使有人为您编辑了它,缩进也有点不稳定,因此仍然难以在脑海中解析。
我不知道你的课程,但对于"真正的"Racket代码,我建议使用
cond
而不是if
。Racket有一个非正式的风格指南,也推荐了这一点。
这里是尾递归
(define (generalized-triangular f n-max)
(let loop ((n 1) (sum 0))
(if (> n n-max)
0
(loop (+ n 1) (+ sum (f n))))))
由于您使用的是球拍标签,因此我认为generalized-triangular
的实现不需要仅使用标准方案。在这种情况下,可以用球拍语言编写一个非常简洁高效的版本(根本不使用if
):
(define (generalized-triangular f n)
(for/sum ([i n]) (f (+ i 1))))
除了标准方案之外,还有两件事需要理解,才能在球拍参考中轻松查找此定义:for/sum
的工作原理以及非负整数用作序列时的行为。