【问题标题】:using lambda instead of let in scheme使用 lambda 而不是 let in 方案
【发布时间】:2023-03-26 07:45:01
【问题描述】:

在 SICP 1.2.1 中有一个生成有理数的函数,如下:

(define (make-rat n d)
  (let ((g (gcd n d)))
    (cons (/ n g) (/ d g))))

我只是好奇如何使用 lambda 而不是 let 来实现相同的功能,而无需两次调用 GCD。我自己也想不通。

【问题讨论】:

    标签: lambda scheme sicp


    【解决方案1】:

    看着SICP section 1.3.2

    (let ((<var1> <exp1>)
          (<var2> <exp2>)
          ...
          (<varn> <expn>))
       <body>)
    

    等价于

    ((lambda (<var1> ...<varn>)
        <body>)
     <exp1>
     ...
     <expn>)
    

    所以你的程序,

    (define (make-rat n d)
      (let ((g (gcd n d)))
        (cons (/ n g) (/ d g))))
    

    应该等价于

    (define (make-rat n d)
      ((lambda (g)
        (cons (/ n g) (/ d g)))
      (gcd n d)))
    

    【讨论】:

      【解决方案2】:

      这两件事是一样的:

      ((lambda (p1 p2...) body) v1 v2...)
      

      (let ((p1 v1) (p2 v2)...) body)
      

      【讨论】:

        【解决方案3】:
        (define-syntax let-as-lambda
          (syntax-rules ()
                ((_ (x value) body)
                    (let ((x value))
                      body))))
        
        (printf "~s~n" (let-as-lambda (x 1) (+ x 1)))
        

        【讨论】:

          【解决方案4】:

          让我们检查两个简单的案例,以便了解如何重写任何使用 let 和 lambda 的函数:

          1. 在我们的第一个例子中,我们有一个 let。这个函数很简单,它通过加 10 来返回给定的输入:

            (define (test x)
              (let ((b 10))
                (+ x b)))
            

          现在让我们使用 lambda 将其转换为表达式:

              (define (test-lambda x)
                ((lambda (b)
                   (+ x b))
                 10))
          

          如您所见,test-lambda 返回一个 lambda 评估,其评估值为 10。测试我们可以说:

              (test-lambda 10)
          

          这将返回 20。

          1. 现在不止一个 let,我们将 lambda 表达式嵌套在 lambda 表达式中。

          我们的 let 案例有两个 let 语句:

              (define (lets x)
                (let ((a 10)
                      (b 20))
                  (+ x a b)))
          

          我们可以像这样用 lambda 写这个:

              (define (lets-lambda x)
                ((lambda (a)
                   ((lambda (b)
                      (+ x a b))
                    20))
                 10))
          

          所以现在我们正在评估每个 lambda 表达式,给它们一个值,最里面的 lambda 表达式使用每个 lambda 表达式已分配的变量名来处理我们想要计算的内容。

          希望这很清楚,可以帮助其他人看得更清楚!

          【讨论】:

            猜你喜欢
            • 2016-07-21
            • 1970-01-01
            • 2018-12-19
            • 1970-01-01
            • 2015-11-17
            • 2013-05-07
            • 1970-01-01
            • 2012-04-04
            • 2011-12-23
            相关资源
            最近更新 更多