对此程序的行为感到困惑

时间:2018-11-11 11:51:42

标签: lambda scheme racket prediction r5rs

(上下文)

我定义了一个过程,该过程将另一个单参数过程对象两次应用于其参数。例如,将inc加1的过程inc,(double inc)将加2。因此(((double inc)5)返回7。

(问题)

我希望[[((double(double(double double))inc)5)返回13。因为double double将应用一个过程4次,因此最左边的double将导致应用一个参数。程序8次。空中的成长。

我错了。在下面查看该过程实际返回的内容。

很明显,我缺少一些东西,但我的理解存在缺陷。

(define (double proc)
(lambda (y) (proc (proc y))))

(define (inc x) (+ x 1))

> ((double inc) 5)
7
> (((double double) inc) 5)
9
> (((double (double double)) inc) 5)
21
> (((double (double (double double))) inc) 5)
261    
> 

2 个答案:

答案 0 :(得分:3)

问题在于您对double嵌套时扩展到的内容的解释。

只需将y替换为inc,一次将其替换为一个级别,您将看到发生了什么事情:

(double inc)使用let的扩展使情况更清晰:

(lambda (y)
        (let ([proc inc])
             ((proc (proc y))))

到目前为止,很好。

((double double) inc)扩展:

     (lambda (y)
        (let ([proc (lambda (y_0) (double (double y_0)))])
             (proc (proc y))))

第一个应用程序可以按预期工作,但是第二个应用程序不将inc函数的应用程序加倍,而是将double函数本身的应用程序加倍,因为您将double应用于函数{{ 1}}在double中。

如果您再次进行操作,即(double double),您会发现它变得混乱...

您可能正在寻找的是将((double (double double) inc)的单个应用程序的结果应用于另一个单个应用程序的结果...

如:

double

答案 1 :(得分:3)

使用原因或替代模型都应该很容易推论得出。

原因:

(double double)

这就像两倍,但两倍,四倍。当应用某个功能时,它将应用该功能4次。

(double (double double))

这是四倍。四倍的结果将变为四倍,使其变为4 * 4。当应用功能时,它将应用16次。

(double (double (double double)))

这是前一个的两倍。然后又一样。 16 * 16使其应用结果256次。

因此(double double)2^2(double (double double))(2^2)^2,而(double (double (double double)))((2^2)^2)^22^8

这与Lambda微积分有关,其中幂定义为λb.λe.e b(lambda (b) (lambda (e) (e b))。现在double2的教堂数字。您看到自己在做((2^2)^2)^2吗?

替换

这里是减少的表情。有时我会跳过一些步骤,因为它几乎发生了几次相同的事情。

((double inc) 5)               ; ==>
((lambda (y) (inc (inc y))) 5) ; ==>
(inc (inc 5))                  ; ==> 7


(((double double) inc) 5)                   ; ==>
(((lambda (y) (double (double y))) inc) 5)  ; ==>
(((lambda (y) (double (double y))) inc) 5)  ; ==>
((double (double inc)) 5)                   ; ==>
((double (lambda (y) (inc (inc y)))) 5)     ; ==>
((lambda (y) ((lambda (y) (inc (inc y))) ((lambda (y) (inc (inc y))) y))) 5) ; ==>
((lambda (y) (inc (inc (inc (inc y))))) 5) ; ==>
(inc (inc (inc (inc 5)))) ; ==> 9


(((double (double double)) inc) 5)                                                                ; ==>
(((double (lambda (y) (double (double y)))) inc) 5)                                               ; ==>
(((lambda (y) ((lambda (y) (double (double y))) ((lambda (y) (double (double y))) y))) inc) 5)    ; ==>
(((lambda (y) (double (double (double (double y))))) inc) 5)                                      ; ==>
((double (double (double (lambda (y) (inc (inc y)))))) 5)                                         ; ==>
((double (double (lambda (y) (inc (inc (inc (inc y))))))) 5)                                      ; ==>
(inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc (inc 5)))))))))))))))) ; ==> 21

我将保留最后一个作为练习。