Recursion 方案:递归zeno函数

Recursion 方案:递归zeno函数,recursion,compilation,scheme,Recursion,Compilation,Scheme,下面是一个函数,求和1/2^n,直到达到0。有人能告诉我是否需要else语句,以及如何安排括号以避免编译错误吗 (define (zeno n) (if (= n 0) (+ 0) (else ((+ (/ 1 (expt 2 n ))) ((zeno(- n 1))))))) 您有几个语法错误(大部分是错误的括号),如果表单没有使用else,请不要误会,它确实有一个“else”部分,只是您不能显式地编写else,它才能工作。我相信

下面是一个函数,求和1/2^n,直到达到0。有人能告诉我是否需要else语句,以及如何安排括号以避免编译错误吗

(define (zeno n)
  (if (= n 0)
      (+ 0)
      (else
        ((+ (/ 1 (expt 2 n )))
         ((zeno(- n 1)))))))

您有几个语法错误(大部分是错误的括号),如果
表单没有使用
else
,请不要误会,它确实有一个“else”部分,只是您不能显式地编写
else
,它才能工作。我相信这就是你的目标:

(define (zeno n)
  (if (= n 0)
      0
      (+ (/ 1 (expt 2 n))
         (zeno (- n 1)))))

您有几个语法错误(大部分是错误的括号),如果
表单没有使用
else
,请不要误会,它确实有一个“else”部分,只是您不能显式地编写
else
,它才能工作。我相信这就是你的目标:

(define (zeno n)
  (if (= n 0)
      0
      (+ (/ 1 (expt 2 n))
         (zeno (- n 1)))))

我有我的帽子,我的茶,还有一段时间的工作无事可做。你知道现在几点了

[唐斯帽]

首先,如果你有你的代码,它会读

(define (zeno n)
    (if (= n 0)
        (+ 0)
        (else
         ((+ (/ 1 (expt 2 n)))
          ((zeno (- n 1)))))))

如果Scheme中的
与类C语言的
构造不同,则
/
/
否则
构造。事实上,这是最重要的。换句话说,
else
在这种情况下毫无意义

(define (zeno n)
    (if (= n 0)
        (+ 0)
        ((+ (/ 1 (expt 2 n)))
         ((zeno (- n 1)))))))

您不需要使用
+
返回数字;数字是自我评估的

(define (zeno n)
    (if (= n 0)
        0
        ((+ (/ 1 (expt 2 n)))
         ((zeno (- n 1)))))))

当你有一个像
(foo-bar-baz)
这样的表达式时,它通常意味着

“使用参数
bar
baz
调用函数
foo

你不能随意加括号;这些改变了表达的意思。例如,
((foo)(bar baz))
表示

不带参数调用函数
foo
,用参数
baz
调用
bar
的结果调用函数的结果

换句话说,

...
((+ (/ 1 (expt 2 n)))
 ((zeno (- n 1))))))
你所说的,几乎肯定不是指,这里是

“调用函数
(+(/1(expt 2 n)))
,结果调用
zeno
的结果,参数
(-n1)
没有参数。”

你的意思是

“将
1
除以
2^n
添加到调用
zeno
的结果中,其中一个小于
n

这意味着你应该说的是

(define (zeno n)
    (if (= n 0)
        0
        (+ (/ 1 (expt 2 n))
           (zeno (- n 1)))))

我有我的帽子,我的茶,还有一段时间的工作无事可做。你知道现在几点了

[唐斯帽]

首先,如果你有你的代码,它会读

(define (zeno n)
    (if (= n 0)
        (+ 0)
        (else
         ((+ (/ 1 (expt 2 n)))
          ((zeno (- n 1)))))))

如果Scheme中的
与类C语言的构造不同,则/
/
否则
构造。事实上,这是最重要的。换句话说,
else
在这种情况下毫无意义

(define (zeno n)
    (if (= n 0)
        (+ 0)
        ((+ (/ 1 (expt 2 n)))
         ((zeno (- n 1)))))))

您不需要使用
+
返回数字;数字是自我评估的

(define (zeno n)
    (if (= n 0)
        0
        ((+ (/ 1 (expt 2 n)))
         ((zeno (- n 1)))))))

当你有一个像
(foo-bar-baz)
这样的表达式时,它通常意味着

“使用参数
bar
baz
调用函数
foo

你不能随意加括号;这些改变了表达的意思。例如,
((foo)(bar baz))
表示

不带参数调用函数
foo
,用参数
baz
调用
bar
的结果调用函数的结果

换句话说,

...
((+ (/ 1 (expt 2 n)))
 ((zeno (- n 1))))))
你所说的,几乎肯定不是指,这里是

“调用函数
(+(/1(expt 2 n)))
,结果调用
zeno
的结果,参数
(-n1)
没有参数。”

你的意思是

“将
1
除以
2^n
添加到调用
zeno
的结果中,其中一个小于
n

这意味着你应该说的是

(define (zeno n)
    (if (= n 0)
        0
        (+ (/ 1 (expt 2 n))
           (zeno (- n 1)))))

对于完全不同的方法,它使用显式的
do
循环进行求和。它避免使用
expt
(通过设计)

将其写入名为
let
的等效格式时,其可读性可能会更高,也可能不会更高:

(define (zeno n)
  (let loop ((n n)
             (sum 0)
             (frac 1/2))
    (if (zero? n)
        sum
        (loop (- n 1) (+ sum frac) (/ frac 2)))))

对于更完全不同的方法,您可以使用streams:


对于完全不同的方法,它使用显式的
do
循环进行求和。它避免使用
expt
(通过设计)

将其写入名为
let
的等效格式时,其可读性可能会更高,也可能不会更高:

(define (zeno n)
  (let loop ((n n)
             (sum 0)
             (frac 1/2))
    (if (zero? n)
        sum
        (loop (- n 1) (+ sum frac) (/ frac 2)))))

对于更完全不同的方法,您可以使用streams:


这不是因为FP舍入误差才起作用吗?这不是因为FP舍入误差才起作用吗?难道你不能把函数简化为(let((base(expt 2n))(/(-base 1)base))?@WorBlux好吧,是的,这是一个公平的观点-P(我已经编辑了我的答案,以合并您建议的解决方案的一个更简单的形式。)您是否也可以通过分析将函数简化为(let((base(expt 2n))(/(-base 1)base))?@WorBlux嗯,是的,这是一个公平的观点:-P(我已经编辑了我的答案,以合并您建议的解决方案的更简单形式。)