Dr.racket初级水平功能

时间:2015-01-23 20:16:43

标签: racket

我是dr.racket的初学者。我被要求编写一个执行以下操作的函数: 编写一个不消耗任何东西的函数“readnum”,每次调用它时,它将产生一个已定义列表的第N个数字。

示例:

(定义一个(列表0 2 -5 0))

readnum - > 0(第一次调用readnum)

readnum - > 2(第二次调用readnum)

readnum - > -5(第三次调用readnum)

你不必担心列表中有数字或没有数字可供阅读的情况。

Dr.racket是一种函数式语言,变异并将它们用作计数器是非常不方便的,在这个问题中,我不允许定义其他全局函数和变量(尽管允许本地)。 这是我的尝试,但它似乎不起作用:

(define counter -1)
(define lstofnum (list 5 10 15 20 32 3 2))
(define (read-num)
((begin(set! counter (+ 1 counter)))
(list-ref lstofnum counter)))

不仅我定义了不允许的全局变量,输出也不是很正确。

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:2)

这里的技巧是在实际定义函数之前声明一个局部变量,这样状态将在闭包内部,我们可以按照我们认为合适的方式更新它。

我们可以使用list-ref实现解决方案并保存当前索引,但不建议这样做。最好将列表和cdr存储在它上面,直到达到它的结尾,这就是我的意思:

(define lstofnum (list 0 2 -5 0))

(define readnum
  (let ((lst lstofnum))              ; list defined outside will be hardcoded
    (lambda ()                       ; define no-args function
      (if (null? lst)                ; not required by problem, but still...
          #f                         ; return #f when the list is finished
          (let ((current (car lst))) ; save the current element
            (set! lst (cdr lst))     ; update list
            current)))))             ; return current element

按预期工作:

(readnum)
=>  0
(readnum)
=>  2
(readnum)
=> -5
(readnum)
=> 0
(readnum)
=> #f