【问题标题】:"application: not a procedure" in binary arithmetic procedures二进制算术程序中的“应用程序:不是程序”
【发布时间】:2013-09-26 08:09:40
【问题描述】:

我有一个简单的 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))))))))

【问题讨论】:

    标签: recursion scheme racket plai


    【解决方案1】:

    在这一行中,您使用(cons 0 x)(rest y) 调用multBins,并得到一些结果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)

    在一个非常简化的情况下,考虑一下 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 会突出显示有问题的调用的位置:

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

    【讨论】:

    • 出色而透彻的解释。去年春天我和 Racket 博士一起做了一些工作,并且处理得很好,但我忘记了这个皱纹。简短的回答是不要使用太多的括号!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多