Recursion &引用;应用:非程序“;在二进制算术程序中

Recursion &引用;应用:非程序“;在二进制算术程序中,recursion,scheme,racket,plai,Recursion,Scheme,Racket,Plai,我有一个简单的二进制数相乘的球拍定义。它使用了一个经过良好测试的“addWithCarry”定义,该定义包含三个参数:两个列表和一个进位数字,并返回二进制和。二进制数以相反顺序表示为列表 我使用调试器逐步完成了测试行,它正确地完成了递归。它会在每次适当收缩y列表时执行multBins,然后按预期执行addWithCarry函数。当它上升回堆栈时,它突然抛出一个异常“application:notprocedure,expected a procedure that can application

我有一个简单的二进制数相乘的球拍定义。它使用了一个经过良好测试的“addWithCarry”定义,该定义包含三个参数:两个列表和一个进位数字,并返回二进制和。二进制数以相反顺序表示为列表

我使用调试器逐步完成了测试行,它正确地完成了递归。它会在每次适当收缩y列表时执行multBins,然后按预期执行addWithCarry函数。当它上升回堆栈时,它突然抛出一个异常“application:notprocedure,expected a procedure that can application to arguments”(应用程序:不是一个过程,应该是一个可应用于参数的过程),参数(0 0 0 1 0 1 1 1)是加在总数上的最高“x”的值。我知道,当您试图将函数的结果作为带参数的函数应用时,可能会发生此错误,但我在这里看不到这一点。看着调试器,一切似乎都在完美地工作,直到最后。有什么想法吗

(define (multBins x y)
  (cond
    ((null? y)       '() )
    ((= (first y) 0) ((multBins (cons 0 x) (rest y))))
    (#t              ((addWithCarry x (multBins (cons 0 x) (rest y)) 0)))))  
(test (multBins '(1 0 1 1)'(1 1 0 1))'(1 1 1 1 0 0 0 1))
以下是addWithCarry的定义:

(define (addWithCarry x y carry)
  (cond
    ((and (null? x)(null? y)) (if (= carry 0) '() '(1)))
    ((null? x) (addWithCarry '(0) y carry))
    ((null? y) (addWithCarry x '(0) carry))
    ( #t  (let ((bit1 (first x))
            (bit2 (first y)))
               (cond
                 ((= (+ bit1 bit2 carry) 0) (cons 0 (addWithCarry (rest x) (rest y) 0)))
                 ((= (+ bit1 bit2 carry) 1) (cons 1 (addWithCarry (rest x) (rest y) 0)))
                 ((= (+ bit1 bit2 carry) 2) (cons 0 (addWithCarry (rest x) (rest y) 1)))
                 (   #t                     (cons 1 (addWithCarry (rest x) (rest y) 1))))))))

在这一行中,您使用
(cons 0 x)
(rest y)
调用
multBins
,并获得一些结果
r
,然后尝试调用
r

(=(第一个y)0)((第二个y)))
;                ^                              ^
;                +--- 函数应用-----+
在下一行中也会发生同样的情况,您正在使用一些参数调用
addWithCarry
,得到一个结果
r
,并尝试调用
r

(#t((addWithCarry x(multBins(cons 0 x)(rest y))0щ);)
;                ^                                                 ^
;                +-------------- 函数应用-------------+
可能其中一个正在返回不适用的值
'(0 0 1 0 1)

<> P>在一个非常简化的情况下,考虑这个来自RelpEnter RePL的誊本:

>(定义(值);返回
'(0 0 0 1 0 1 1))    ; 和你的价值一样
>(价值);调用它会产生值
(0 0 0 1 0 1 1)
>((价值));先打电话,然后再打电话
; 返回值会导致相同的错误
; 你看到的错误
; 应用:不是一个程序;
; 应为可应用于参数的过程
;  给定:(0 0 1 0 1 1)
;  参数…:[无]
您没有提到您正在使用的编辑器/IDE/调试器,但有些应该使它更容易发现。例如,当我加载您的代码时(减去对
test
的调用,我没有该调用的定义,以及
first
rest
的定义),DrRacket会突出显示违规调用的位置:


虽然我指出的两个有问题的调用都需要修复,但您现在看到的错误发生在这两个调用中的第二个。

非常好且彻底的解释。去年春天,我和Racket博士做了一些工作,并且有一个不错的手柄,但我忘记了这条皱纹。简而言之,不要用太多的括号!