我在函数中实现一个名为fib
的生成器时遇到问题。
我希望函数返回一个生成器,该生成器生成第一个n
斐波那契数。
;THIS IS MY GENERATOR
(define fib
(let ((a 0) (b 1))
(lambda ()
(let ((return a))
(set! a b)
(set! b (+ b return)
)return))))
;THIS IS MY FUNCTION
(define (take n g)
(define fib
(let ((a 0) (b 1) (cont 1))
(lambda ()
(if (>= cont n) #f
(let ((return a))
(set! cont (+ cont 1))
(set! a b)
(set! b (+ b return)
)(return)))))))
我希望生成器返回斐波纳契数直至N
(传递给函数)。但是实际输出是:
开始(可能是隐式的):在以下一系列内部定义之后没有表达式:
(begin (define fib (let ((a 0) (b 1) (cont 1)) (lambda () (if (>= cont n) #f (let ((return a)) (set! cont (+ cont 1)) (set! a b) (set! b (+ b return)) (return)))))))
答案 0 :(得分:2)
正如错误所言,函数定义中没有表达式,除了一些内部定义(显然,它被包含在隐式begin
中)。定义好之后,要执行的功能是什么?
更重要的是,您的解决方案的整体设计存在问题。
在编写函数的定义时,请立即记下其示例调用,这样您就可以知道应该如何/打算/如何调用它。特别是
(define (take n g)
建议您将其命名为(take 10 fib)
,以便在take
的定义g
中获得fib
的值。
但是fib
是一个 global 生成器。在不同的调用之间,它不能以任何方式重新启动。这就是为什么您开始复制其源代码,然后又意识到,为什么要使用g
参数呢?那里不太合适。
您需要在需要时创建一种新的新鲜斐波那契发生器的方法:
(define (mk-fib)
(let ((a 0) (b 1))
(lambda ()
(let ((ret a))
(set! a b)
(set! b (+ ret b))
ret)))) ;; ..... as before .....
现在,每个(mk-fib)
调用都将创建并返回一个新的斐波那契数字生成器,因此现在 可以用作take
调用的参数:>
(define (taking n g) ;; (define q (taking 4 (mk-fib)))
现在,无需像以前尝试的那样定义同一全局fib
生成器的新本地副本。我们只有take
本身的特定内容:
(let ((i 1))
(lambda () ; a generator interface is a function call
(if (> i n) ; not so good: what if #f
#f ; is a legitimately produced value?
(begin
(set! i (+ i 1))
(g)))))) ; a generator interface is a function call
现在我们可以定义
> (define q (taking 4 (mk-fib)))
> (q)
0
> (q)
1
> (q)
1
> (q)
2
> (q)
#f
> (q)
#f
>