在方案中使用lambda而不是let

时间:2010-05-25 16:39:33

标签: lambda scheme sicp

在SICP 1.2.1中,有一个函数可以得到一个有理数,如下所示:

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

我只是好奇你如何使用lambda而不是let来实现相同的东西,而不需要两次调用GCD。我自己无法理解。

4 个答案:

答案 0 :(得分:13)

查看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)))

答案 1 :(得分:10)

这两件事情是一样的:

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

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

答案 2 :(得分:1)

(define-syntax let-as-lambda
  (syntax-rules ()
        ((_ (x value) body)
            (let ((x value))
              body))))

(printf "~s~n" (let-as-lambda (x 1) (+ x 1)))

答案 3 :(得分:1)

让我们检查两个简单的情况,以便我们可以理解如何重写使用lambda的let函数:

  1. 在我们的第一个案例中,我们有一个让。这个函数非常简单,它通过向它添加10来返回给定的输入:

    (define (test x)
      (let ((b 10))
        (+ x b)))
    
  2. 现在让我们把它变成一个使用lambda的表达式:

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

    正如您所看到的,test-lambda返回一个使用值10计算的lambda评估。测试这个我们可以说:

        (test-lambda 10)
    

    将返回20。

    1. 现在有多个let,我们在lambda表达式中嵌套lambda表达式。
    2. 我们的let case有两个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表达式已经赋值的变量名称来处理我们想要计算的内容。

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