【问题标题】:Using local variables in scheme在方案中使用局部变量
【发布时间】:2014-02-11 04:40:01
【问题描述】:

我被要求将几个 C 函数转换为分配方案。我的教授非常简短地讨论了 Scheme 的工作原理,我发现它很难理解。我想创建一个函数来检查哪个数字大于另一个,然后在每次输入新数字时继续检查。我遇到的问题是变量声明。我不明白您如何为 id 赋值。

(define max 1)

(define (x x)
  (let maxfinder [(max max)]
    (if (= x 0)
        0
        (if (> max x) 
            max
            ((= max x) maxfinder(max))))))

我一直遇到的麻烦是我想将 max 初始化为常量,并修改 x.在我看来,这被设置为一个无限循环,当 x = 0 时退出。如果 max > x,它不应该是第一次通过,然后将 max = 设置为 x,并返回 x。我不知道如何处理常数最大值。我需要它是一个局部变量。谢谢

【问题讨论】:

    标签: variables scheme local


    【解决方案1】:

    括号的使用非常严格。除了特殊形式外,它们还用于调用过程。例如(> max x) 使用参数maxx 调用过程>((if (> x 3) - +) 6 x) 是 if 表单返回过程并调用结果的示例。

    • ((= max x) ...)(= max x) 求值,因为结果不是一个过程,所以它会失败。
    • maxfinder 不带括号只是一个过程对象。
    • (max) 不起作用,因为 max 是一个数字,而不是一个过程。

    至于你的问题。在命名的 let 中添加需要更改的额外变量。例如。一个过程,它接受一个数字 n 并创建一个数字 0-n 的列表。

    (define (make-numbered-list n)
      (let loop ((n n) (acc '()))
        (if (zero? n)
            acc
            (loop (- n 1) (cons n acc)))))
    

    局部变量只是局部绑定的符号。这可以重写

    (define (make-numbered-list n)
      (define (loop n acc)
        (if (zero? n)
            acc
            (loop (- n 1) (cons n acc))))
      (loop n '()))
    

    与 C 等 Algol 方言不同,您不会在循环中改变变量,而是使用 recusion 来改变它们。

    祝你好运

    【讨论】:

      【解决方案2】:

      如果我对您的理解正确,您正在寻找 C 函数的静态变量的等价物。这在 Scheme 中称为closure

      这是一个你输入数字的函数的示例实现,它总是返回当前最大值:

      (define maxfinder
        (let ((max #f))                    ; "static" variable, initialized to False
          (lambda (n)                      ; the function that is defined
            (when (or (not max) (< max n)) ; if no max yet, or new value > max
              (set! max n))                ; then set max to new value
            max)))                         ; in any case, return the current max
      

      然后

      > (maxfinder 1)
      1
      > (maxfinder 10)
      10
      > (maxfinder 5)
      10
      > (maxfinder 2)
      10
      > (maxfinder 100)
      100
      

      所以这会起作用,但没有提供在不同上下文中重用函数的机制。以下更通用的版本在每次调用时都会实例化一个新的函数

      (define (maxfinder)
        (let ((max #f))                    ; "static" variable, initialized to False
          (lambda (n)                      ; the function that is returned
            (when (or (not max) (< max n)) ; if no max yet, or new value > max
              (set! max n))                ; then set max to new value
            max)))                         ; in any case, return the current max
      

      这样使用:

      > (define max1 (maxfinder)) ; instantiate a new maxfinder
      > (max1 1)
      1
      > (max1 10)
      10
      > (max1 5)
      10
      > (max1 2)
      10
      > (max1 100)
      100
      
      > (define max2 (maxfinder)) ; instantiate a new maxfinder
      > (max2 5)
      5
      

      【讨论】:

        【解决方案3】:

        定义一个函数来确定两个数字之间的最大值:

        (define (max x y)
          (if (> x y) x y))
        

        定义一个函数来“结束”

        (define end? zero?)
        

        定义一个函数循环直到end?计算max

        (define (maximizing x)
          (let ((input (begin (display "number> ") (read))))
            (cond ((not (number? input)) (error "needed a number"))
                  ((end? input) x)
                  (else (maximizing (max x input))))))
        

        开始吧:

        > (maximizing 0)
        number> 4
        number> 1
        number> 7
        number> 2
        number> 0
        7
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-17
          • 1970-01-01
          • 2015-07-16
          • 2015-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多