方案lambda并让错误

时间:2017-11-14 13:50:26

标签: lambda scheme racket

计划中的初学者..尝试使用以下代码来测试lambda的等价性并让

(lambda (x y)
  (+ x y)
  10
  (* x 2))

(let ((k 10)
      (y (* 2 k)))
  (+ k y))

输出

#<procedure>
. . k: undefined;
 cannot reference undefined identifier
> 

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:0)

Scheme let有两个限制。

  1. let定义的变量对后续定义的主体不可见。
  2. let定义的变量对定义本身不可见。
  3. 第一个限制适用于您的示例。

    (let ((k 10)
          (y (* 2 k)))
      (+ k y))
    

    在此示例中,ky在同一let中定义。 y的正文确实知道k。为了使k的正文y可见,您必须使用两个let表达式。

    (let ((k 10))
      (let ((y (* 2 k)))
        (+ k y)))
    

    为了避免这种嵌套,Scheme提供了let*替代方案。

    (let* ((k 10)
           (y (* 2 k)))
      (+ k y))
    

    如果您阅读let*的规范,则还应考虑阅读letrec的规范,这将消除第二个限制。

答案 1 :(得分:0)

FWIW,相当于lambda构造

(let ((k 10))
  (let ((y (* 2 k)))
    (+ k y)))

((lambda (k)
   ((lambda (y)
      (+ k y))
    (* 2 k)))
 10)

答案 2 :(得分:0)

let形式的正文之前不能使用let中的绑定。因此,您需要定义k

(define k 99)

(let ((k 10)
      (y (* 2 k))) ; the k here is not the one in the same `let`
  (+ k y))
; ==> 208

let只是被称为匿名过程的语法糖。它等于这个:

((lambda (k y)
   (+ k y))
 10
 (* 2 k))

使用此语法可能更明显k不能分配给10?还有另一种称为let*的语法,它允许您使用以前的绑定:

(let* ((k 10)
       (y (* 2 k))) ; the k here is not the one in the same `let`
  (+ k y))
; ==> 30

它等于嵌套的匿名过程调用:

((lambda (k)
   ((lambda (y)
      (+ k y))
    (* 2 k)))
 10)

此处很容易看到k中的(* 2 k)是绑定到10的{​​。}}。