【问题标题】:I have some difficult in understanding Scheme Source Code我在理解方案源代码方面有些困难
【发布时间】:2016-06-24 06:13:28
【问题描述】:

以下是我为该问题下载的示例代码: 计数器加一,修改它以将用于递增的值作为参数传递。 例如,

(let ((c (create-counter))) (+ (c) (c) (c) (c))) => 6
(let ((c (create-counter 2))) (+ (c) (c) (c) (c))) => 12

源代码:

(define create-counter
 (lambda ([num '()]) 
   (let ((temp (lambda (incr)  
           (let* ((start (- incr))
                (count start))
           (lambda num
             (set! count (+ incr count)) count)))))
       (if (null? num)
         (temp 1)
         (temp num)))))

这是我自己的代码:

(define create-counter
      (let ([count 0])
        (lambda ([x '()])
      (cond
        [(null? x) (set! count (+ 1 count)) (- count 1)]
        [(> x 0)(set! count (+ x count)) (- count x)])
      )))

对于闭包句柄等,我对 let 和 lambda 有一点了解。但是,对于这个极端的问题,我仍然不知道如何像示例代码那样编写。我的代码通过以下示例完成计算:

(+ (create-counter 2) (create-counter 2) (create-counter 2) (create-counter 2)) -> 12

但是我的代码不适用于示例测试用例。我有时会得到 0 或错误。

我必须修改我的源代码才能作为示例运行和工作?请帮助我更好地理解这个范围和闭包,任何提示将不胜感激。谢谢你,对不起我的英语不好。

【问题讨论】:

    标签: lambda scheme racket counter let


    【解决方案1】:

    您下载的代码过于复杂。

    你的更好,但是对于谁获得指定增量的参数存在混淆。 create-counter 是一个返回过程的过程,但它是您要为其提供参数的第一个,而不是第二个。

    另外,既然可以使用默认值 1,为什么还要使用默认值 '()?所以你的代码变成了:

    (define (create-counter (x 1))
      (let ([count 0])
        (lambda ()
          (set! count (+ x count))
          (- count x))))
    

    顺便说一句...您可以将count的初始值放入一个临时变量中并返回,或者只使用begin0,而不是再次添加x和减去x

    (define (create-counter (incr 1))
      (let ((val 0))
        (lambda ()
          (begin0
            val
            (set! val (+ val incr))))))
    

    甚至更短,并且可以选择将初始值设置为 0 以外的值:

    (define (create-counter (incr 1) (val 0))
      (lambda ()
        (begin0
          val
          (set! val (+ val incr)))))
    

    测试:

    > (let ((c (create-counter))) (+ (c) (c) (c) (c))) ; => 6
    6
    > (let ((c (create-counter 2))) (+ (c) (c) (c) (c))) ; => 12
    12
    

    但这不适用于

    (+ (create-counter 2) (create-counter 2) (create-counter 2) (create-counter 2)) ; -> 12
    

    因为这里你希望create-counter 返回一个数值,但实际上它返回了一个过程。

    【讨论】:

    • 是否有“begin0”的等效代码?使用 lambda() 我总是可以将函数的值返回到我的函数定义的闭包中,对吗?
    • 之所以使用begin0,是为了返回计数器的当前值,然后再对其进行迭代。如果你不想使用begin0,它看起来像这样(λ () (let ((x val)) (set! val (+ val incr)) x))
    • 非常感谢您向我详细解释。我现在明白了这个问题。
    猜你喜欢
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2011-01-13
    相关资源
    最近更新 更多