2016-11-20 79 views
1

默认情况下,球拍内置了一个make-posn。这是一个lambda实现。Posn in scheme/DrRacket

(define (my-make-posn x y) 
    (lambda (s) 
    (cond [(symbol=? s 'x) x] 
      [(symbol=? s 'y) y])) 

但这返回(lambda (a1) ...)当我尝试(my-make-posn 3 2)

这是为什么?

我不明白lambda在这里是如何使用的?

我们键入(my-make-posn 3 2)和函数体是:

(lambda (s) 
    (cond [(symbol=? s 'x) x] 
     [(symbol=? s 'y) y])) 

那么会发生什么情况(3, 2)

+0

请不要破坏你的问题 - 如果你想添加更多的内容或其他问题,继续。如果您想查询答案,请在评论中填写。 –

回答

0

你打电话给my-make-posn错了;你应该通过符号来访问约束变量来代替:

> ((my-make-posn 3 2) 'x) 
3 
> ((my-make-posn 3 2) 'y) 
2 

拉姆达被用于有条件地返回xy

0

posn的这种“编码”利用了lambda是词汇关闭的事实。这意味着lambda可以访问定义范围内的值,即使它们是本地绑定。例如,考虑这个简单的使用,它返回一个lambda函数:

(define (make-adder x) 
    (lambda (y) (+ x y))) 

这是一个返回函数的函数。结果函数带有一个参数。你可以看到它是如何使用这样的:

> (define add1 (make-adder 1)) 
> (add1 1) 
2 
> (add1 2) 
3 
> (define add2 (make-adder 2)) 
> (add2 1) 
3 
> (add2 2) 
4 

由于功能只是普通的值,也可以直接使用生成的功能,不绑定到一个变量名:

> ((make-adder 10) 5) 
15 

如何做到这一点工作?那么考虑一下make-adder的定义。内部lambda使用x,这是make-adder函数的参数。由于lambda是关闭,这是完全正常的,并且x实际上变为“锁定”到提供给make-adder的值;也就是x被内部lambda“封闭”,因此名称。

对于这个更具体的例子,你能想象评估make-adder作为一种替代的:

1. (make-adder 1) ; given 

2. ((lambda (x)  ; substitution of the 
     (lambda (y) ; definition of make-adder 
     (+ x y))) 
    1) 

3. (lambda (y)  ; lambda reduction, substituting 
    (+ 1 y))  ; 1 for x within the body 

同样的事情正被用于my-make-posn。我们可以做同样的扩张为(my-make-posn 3 2)

1. (my-make-posn 3 2)     ; given 

2. ((lambda (x y)      ; substitution of the 
     (lambda (s)      ; definition of my-make-posn 
     (cond [(symbol=? s 'x) x] 
       [(symbol=? s 'y) y]))) 
    3 2) 

3. (lambda (s)       ; lambda reduction, substituting 
    (cond [(symbol=? s 'x) 3]   ; 3 for x and 2 for y within the body 
      [(symbol=? s 'y) 2])) 

因此,结果是一个函数,它的象征,无论是'x'y,并产生提供给原始my-make-posn函数的两个参数之一。