[英]Scheme: recursive zeno function
The following is a function that sums 1/2^n until it reaches 0 . 以下是一个将1/2 ^ n加到0的函数。 Can someone tell me whether or not I need an else statement, and how to arrange my parenthesis so there are no compile errors?
有人可以告诉我是否需要else语句,以及如何排列括号以确保没有编译错误吗?
(define (zeno n)
(if (= n 0)
(+ 0)
(else
((+ (/ 1 (expt 2 n )))
((zeno(- n 1)))))))
I have my hat, my tea, and nothing to do for a while at work. 我戴上帽子,喝茶,上班没时间做。 You know what time it is.
你知道现在几点了。
[dons code-review hat] [不带密码审查帽]
Firstly, if you had properly indented your code, it would read 首先,如果您正确缩进了代码,它将显示为
(define (zeno n)
(if (= n 0)
(+ 0)
(else
((+ (/ 1 (expt 2 n)))
((zeno (- n 1)))))))
if
in Scheme is not like the if
/ then
/ else
construct of C-like languages. if
in Scheme不像C语言一样的if
/ then
/ else
构造。 It's actually the ternary operator . 实际上是三元运算符 。 In other words,
else
makes no sense in this context. 换句话说,在这种情况下,
else
毫无意义。
(define (zeno n)
(if (= n 0)
(+ 0)
((+ (/ 1 (expt 2 n)))
((zeno (- n 1)))))))
You don't need to use +
to return a number; 您不需要使用
+
来返回数字; numbers are self-evaluating. 数字是自我评估的。
(define (zeno n)
(if (= n 0)
0
((+ (/ 1 (expt 2 n)))
((zeno (- n 1)))))))
When you have an expression like (foo bar baz)
, it usually means 当您具有
(foo bar baz)
这样的表达式时,通常表示
"Call the function
foo
with argumentsbar
andbaz
"“使用参数
bar
和baz
调用函数foo
”
You can't just add extra parentheses as you please; 您不能随便添加多余的括号。 those change the meaning of the expression.
这些改变了表达的含义。 For example,
((foo) (bar baz))
means 例如,
((foo) (bar baz))
意思是
"Call the function
foo
with no arguments, and call its result with the result of callingbar
with the argumentbaz
"“不带参数调用函数
foo
,并以带参数baz
调用bar
的结果来调用其结果”
In other words, 换一种说法,
...
((+ (/ 1 (expt 2 n)))
((zeno (- n 1))))))
what you're saying, and almost certainly don't mean, here is 您在说什么,几乎可以肯定不是在这里,这是
"Call the function
(+ (/ 1 (expt 2 n)))
with the result of calling the result of callingzeno
with the argument(- n 1)
with no arguments."“调用函数
(+ (/ 1 (expt 2 n)))
的结果是调用不带参数的参数(- n 1)
调用zeno
的结果。”
What you seem to mean is 你似乎的意思是
"Add
1
divided by2^n
to the result of callingzeno
with one less thann
"“将调用
zeno
的结果加1
除以2^n
,且n
小于n
”
Which means that what you should say is 这意味着您应该说的是
(define (zeno n)
(if (= n 0)
0
(+ (/ 1 (expt 2 n))
(zeno (- n 1)))))
You have a couple of syntax errors (erroneous parenthesis, mostly), and the if
form doesn't use else
- don't get me wrong, it does have an "else" part, it's just that you must not explicitly write else
for it to work. 你有几个语法错误(错误的括号内,多),并且
if
形式不使用else
-不要误会我的意思,它确实有一个“其他”的一部分,它只是你不能明确写入else
的它起作用。 I believe this is what you were aiming for: 我相信这就是您的目标:
(define (zeno n)
(if (= n 0)
0
(+ (/ 1 (expt 2 n))
(zeno (- n 1)))))
For a completely different approach, this uses an explicit do
loop to do the summing. 对于完全不同的方法,这使用显式的
do
循环进行求和。 It avoids using expt
(by design). 它避免使用
expt
(通过设计)。
(define (zeno n)
(do ((n n (- n 1))
(sum 0 (+ sum frac))
(frac 1/2 (/ frac 2)))
((zero? n) sum)))
It may or may not be more readable when written into its equivalent named let
form: 将其写入等效的名为
let
形式时,它可能会或可能不可读:
(define (zeno n)
(let loop ((n n)
(sum 0)
(frac 1/2))
(if (zero? n)
sum
(loop (- n 1) (+ sum frac) (/ frac 2)))))
For an even more completely different approach, you can use SRFI 41 streams: 对于更完全不同的方法,可以使用SRFI 41流:
(define zeno
(let ((frac-stream (stream-iterate (cut / <> 2) 1/2)))
(lambda (n)
(stream-fold + 0 (stream-take n frac-stream)))))
(The above snippet also requires SRFI 26 to be loaded, in addition to SRFI 41.) (以上代码段也需要SRFI 26被加载,除了SRFI 41)
An even even more completely different approach: just use the closed-form solution! 甚至更完全不同的方法:仅使用封闭形式的解决方案! (Thanks, WorBlux.)
(谢谢,WorBlux。)
(define (zeno n)
(- 1 (/ (expt 2 n))))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.