二进制算术程序中的“应用程序:不是程序”

时间:2013-09-26 08:09:41

标签: recursion scheme racket plai

我有一个简单的Racket定义,用于将二进制数相乘。它使用经过充分测试的“addWithCarry”定义,该定义采用三个参数:两个列表和一个进位数,并返回二进制和。二进制数以相反的顺序表示为列表。

我使用调试器逐步完成了测试行,并且正确地完成了递归。它每次在适当时缩小y列表时执行multBins,然后按预期执行addWithCarry函数。当它上升到堆栈时,它突然抛出一个异常“应用程序:不是一个过程,期望一个可以应用于参数的过程”,参数为'(0 0 0 1 0 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))))))))

1 个答案:

答案 0 :(得分:5)

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

((= (first y) 0) ((multBins (cons 0 x) (rest y))))
;                ^                              ^
;                +--- function application -----+

在下一行中发生了同样的事情,您使用一些参数调用addWithCarry,获得结果r,然后尝试调用r

(#t              ((addWithCarry x (multBins (cons 0 x) (rest y)) 0)))))
;                ^                                                 ^
;                +-------------- function application -------------+

推测其中一个返回了不适用的值'(0 0 0 1 0 1 1)

very 简化案例中,请考虑DrRacket REPL的这个记录:

> (define (value)        ; a function that returns the 
    '(0 0 0 1 0 1 1))    ; same value that yours should

> (value)                ; calling it produces the value 
(0 0 0 1 0 1 1)

> ((value))              ; calling it and then calling
                         ; return value causes the same
                         ; error that you're seeing
; application: not a procedure;
; expected a procedure that can be applied to arguments
;  given: (0 0 0 1 0 1 1)
;  arguments...: [none]

你没有提到你正在使用的编辑器/ IDE /调试器,但有些人应该更容易发现它。例如,当我加载您的代码时(减去对test的调用,我没有定义,以及firstrest的定义),DrRacket会突出显示该代码的位置。违规电话:

bad code highlighted in DrRacket IDE

虽然我指出的两个有问题的电话需要修复,但你现在看到的错误发生在两个中的第二个。