作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在执行代码的过程中,我在不同的Scheme实现中遇到以下错误:
Racket :
application: not a procedure;
expected a procedure that can be applied to arguments
given: '(1 2 3)
arguments...:
Unhandled exception
Condition components:
1. &assertion
2. &who: apply
3. &message: "not a procedure"
4. &irritants: ((1 2 3))
Error: call of non-procedure: (1 2 3)
*** ERROR IN (console)@2.1 -- Operator is not a PROCEDURE
((1 2 3) 4)
;The object (1 2 3) is not applicable.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify a procedure to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
Exception: attempt to apply non-procedure (1 2 3)
Type (debug) to enter the debugger.
ERROR: In procedure (1 2 3):
ERROR: Wrong type to apply: (1 2 3)
ERROR in final-resumer: non procedure application: (1 2 3)
最佳答案
为什么会这样
方案过程/函数调用如下所示:
(operator operand ...)
运算符和操作数都可以是变量
test
和
+
,它们的值不同。为了使过程调用起作用,它必须是过程。从错误消息看来,
test
似乎不是过程,而是列表
(1 2 3)
。
((proc1 4) 5)
这样的语法是有效的语法,并且期望
(proc1 4)
调用返回一个过程,然后将
5
作为其唯一参数进行调用。
(if (< a b)
((proc1)
(proc2))
#f)
当谓词/测试为true时,Scheme会尝试同时评估
(proc1)
和
(proc2)
,然后由于括号会调用
(proc1)
的结果。要在Scheme中创建一个块,请使用
begin
:
(if (< a b)
(begin
(proc1)
(proc2))
#f)
在此
(proc1)
中,仅是为了效果而调用,而teh form的结果将是最后一个表达式
(proc2)
的结果。
(define (test list)
(list (cdr list) (car list)))
这里的参数称为
list
,它使过程
list
在调用期间不可用。在Scheme中,一个变量只能是一个过程或不同的值,最接近的绑定(bind)是您在运算符和操作数位置都获得的绑定(bind)。这将是普通用户犯的一个典型错误,因为在CL中,他们可以将
list
用作参数而不会弄乱函数
list
。
cond
中
(define test #t) ; this might be result of a procedure
(cond
((< 5 4) result1)
((test) result2)
(else result3))
尽管谓词表达式
(< 5 4)
(test)
看起来是正确的,因为它是一个用于检查深度的值,但它与
else
术语有更多共同之处,应该这样写:
(cond
((< 5 4) result1)
(test result2)
(else result3))
应该返回过程的过程并不总是
(define (test v)
(if (> v 4)
(lambda (g) (* v g))
'(1 2 3)))
((test 5) 10) ; ==> 50
((test 4) 10) ; ERROR! application: not a procedure
未定义的值,例如#<void>
,#!void
,#<undef>
和#<unspecified>
set!
,
set-car!
,
set-cdr!
,
define
之类的形式返回的值。
(define (test x)
((set! f x) 5))
(test (lambda (x) (* x x)))
该代码的结果不确定,因为
set!
可以返回
任何值,而且我知道某些方案实现(例如MIT Scheme)实际上返回绑定(bind)值或原始值,结果将是
25
或
10
,但是在许多实现中,您得到的都是常数像
#<void>
这样的值,由于它不是一个过程,因此您会遇到相同的错误。依靠规范下使用的一种实现方法,可以使您获得不可移植的代码。
(define (double v f)
(f (f v)))
(double 10 (lambda (v) (* v v))) ; ==> 10000
如果您错误地交换了参数:
(double (lambda (v) (* v v)) 10) ; ERROR: 10 is not a procedure
在更高阶的函数(例如
fold
和
map
)中,如果未以正确的顺序传递参数,则会产生类似的错误。
fun
与参数
arg
一起应用时,它看起来像:
fun(arg)
在Scheme中,这被解释为两个单独的表达式:
fun ; ==> valuates to a procedure object
(arg) ; ==> call arg with no arguments
以
fun
作为参数应用
arg
的正确方法是:
(fun arg)
多余的括号
((+ 4 5))
这样的代码在Scheme中不起作用,因为此表达式中的每个括号都是一个过程调用。您根本无法添加任意多的内容,因此需要将其保留为
(+ 4 5)
。
abs
的示例:
(define (abs x)
((if (< x 0) - values) x))
这在执行
(- x)
和
(values x)
(返回其参数的身份)之间切换,并且您可以看到它调用表达式的结果。这是使用cps的
copy-list
的示例:
(define (copy-list lst)
(define (helper lst k)
(if (null? lst)
(k '())
(helper (cdr lst)
(lambda (res) (k (cons (car lst) res))))))
(helper lst values))
注意
k
是我们传递函数的变量,它被称为函数。如果我们通过了除功能以外的任何其他功能,那么您将得到相同的错误。
function double (f, v) {
return f(f(v));
}
double(v => v * v, 10); // ==> 10000
double(10, v => v * v);
; TypeError: f is not a function
; at double (repl:2:10)
// similar to having extra parentheses
function test (v) {
return v;
}
test(5)(6); // == TypeError: test(...) is not a function
// But it works if it's designed to return a function:
function test2 (v) {
return v2 => v2 + v;
}
test2(5)(6); // ==> 11
关于runtime-error - 我的代码显示错误 “application: not a procedure”或 “call to non procedure”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48064955/
我是一名优秀的程序员,十分优秀!