尝试在此代码中检查输入号是否为偶数:
(define (square n)
(* n n))
(define (smallest-divisor n)
(find-divisor n 2))
(define (find-divisor n test-divisor)
(cond
((> (square test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(define (divides? a b)
(= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
(define (runtime)
(current-milliseconds))
(define (timed-prime-test n)
(newline)
(display n)
(start-prime-test n runtime 1))
(define (start-prime-test n start-time count)
(if (prime? n)
(report-prime (- (runtime) start-time)
(+ count 1)
(display "tut"))
(+ n 1))
(if (even? n)
(+ n 1)
(display "n is uneven"))
(if (= count 3)
(display "done")
(start-prime-test (+ n 1) runtime count)))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
(timed-prime-test 4)
看到此错误:
contract violation expected: number? given: #<procedure:runtime> argument position: 2nd other arguments...: 1535481725945
有人可以告诉我怎么了吗?
答案 0 :(得分:1)
第一个问题是runtime
函数的两次使用。该错误消息表明它得到了 function runtime
,该位置应有数字。可能是调用函数的结果。这意味着您在某处引用该函数而不调用它。
此:
> runtime
#<procedure:runtime>
代替此:
> (runtime)
1535490725945
请记住,要调用一个函数,即使它是一个零参数的函数,也必须将其包装在括号中。
您在3个地方使用了runtime
函数,在其中2个地方(在timed-prime-test
内和start-prime-test
的第3个if语句中),您使用的是裸函数,而没有调用它。
将这两个位置从runtime
更改为(runtime)
可以消除contract violation expected: number? given: #<procedure:runtime>
错误。
这解决了您的第一个问题。
但是背后还有另一个错误:
report-prime: arity mismatch; the expected number of arguments does not match the given number expected: 1 given: 3 arguments...: 0 2 #<void>
这来自您在report-prime
函数的第一个if语句中对start-prime-test
的调用。
我不知道您打算将此代码或report-prime
函数用于什么。可能是定义错误,应该使用更多参数,也可能是调用错误,并且只能传入一个参数。
您打算选哪个人?
report-prime
,然后执行2个操作我只想向其中传递1个参数(
(- (runtime) start-time)
),并且在它执行功能后,我要始终执行两个操作((+ count 1)
和(display "tut")
)
要执行一系列操作,应使用begin
,如下所示:
(begin
action1
action2
...)
现在,(+ count 1)
不是一个“动作”,但这是一个单独的问题。如果您打算将其用作操作,则它将进入此begin
块内。
这意味着在start-prime-test
的第一个if语句中,替换为:
(report-prime (- (runtime) start-time)
(+ count 1)
(display "tut"))
与此:
(begin
(report-prime (- (runtime) start-time))
(+ count 1)
(display "tut"))
有了这一更改,report-prime: arity mismatch
错误就消失了。
这解决了您的第二个问题。
这背后还有另一个问题,无限循环。您的代码将显示:
4 *** 0tutn is uneven *** 0tutn is unevenn is uneven *** 0tutn is uneven *** 0tutn is unevenn is uneven *** 0tutn is uneven *** 0tutn is unevenn is uneven *** 0tutn is unevenn is unevenn is uneven *** 0tutn is uneven *** 0tutn is unevenn is unevenn is uneven *** 0tutn is unevenn is uneven *** 0tutn is uneven *** 0tutn is unevenn is uneven *** 0tutn is unevenn is unevenn is uneven *** 0tutn is unevenn is unevenn is uneven *** 0tutn is uneven *** 0tutn is unevenn is unevenn is uneven *** 0tutn is unevenn is uneven *** 0tutn is uneven *** 0tutn is unevenn is unevenn is uneven *** 0tutn is unevenn is uneven *** 0tutn is unevenn is unevenn is uneven *** 0tutn is unevenn is uneven
它一直这样,永不停止。
我建议您提出一个单独的问题来解决此问题,因为无限循环是与合同违约相比要解决的另一种问题。
但是,首先,您可能想阅读有关如何在函数式编程中使用递归的教程。要点是,需要有一个基本案例,该案例总是停止的,而任何递归案例都需要与该基本案例“更接近”,以了解更接近的定义。