Как говорится в ошибке, у вас нет выражений в определении вашей функции, за исключением некоторого внутреннего определения (которое, очевидно, заложено в неявное begin
).Определив ее, что должна делать функция?
Что еще более важно, есть проблемы с общим дизайном вашего решения.
При написании определения функции сразу запишите ее примеры вызовов, чтобы выПосмотрите, как это предполагается / предназначено / будет называться.В частности,
(define (take n g)
предполагает, что вы намереваетесь назвать его как (take 10 fib)
, так что внутри определения take
g
будет получено значение fib
.
Но fib
- это один глобальный генератор.Он никак не может быть перезапущен между различными вызовами.Вот почему вы начали копировать его источник, но потом, возможно, поняли, почему тогда у параметра 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
>