ожидается нарушение договора: номер? задано: # <процедура: время выполнения> позиция аргумента: 2 других аргумента ...: 1535481725945 - PullRequest
0 голосов
/ 28 августа 2018

Попробуйте проверить число вхождения до четного в этом коде:

(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

Может кто-нибудь сказать мне, что не так?

1 Ответ

0 голосов
/ 29 августа 2018

Первая проблема связана с двумя вариантами использования функции runtime. Сообщение об ошибке говорит, что он получил функцию runtime, где он ожидал число; вероятно, результат вызова функции. Это означает, что где-то вы ссылаетесь на функцию, не вызывая ее.

Это:

> runtime
#<procedure:runtime>

Вместо этого:

> (runtime)
1535490725945

Имейте в виду, что для вызова функции необходимо заключить ее в скобки, даже если это функция с нулевым аргументом.

Вы используете функцию runtime в 3 местах, а в 2 из них (в пределах timed-prime-test и в 3-м, если оператор start-prime-test) вы используете голую функцию, не вызывая ее.

Изменение этих 2 мест с 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 с 1 аргументом, а затем выполнение 2 действий

Я хочу передать в него только 1 параметр ((- (runtime) start-time)), и после того, как он выполнит функцию, я хочу последовательно выполнить два действия ((+ count 1) и (display "tut"))

Чтобы выполнить кучу действий, вы должны использовать begin следующим образом:

(begin
  action1
  action2
  ...)

Теперь (+ count 1) - это не «действие», но это отдельная проблема. Если бы вы намеревались сделать это действием, то оно было бы включено в этот блок begin.

Это означает, что в первом операторе if start-prime-test следует заменить это:

(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

И так продолжается, не останавливаясь.

Я предлагаю вам задать отдельный вопрос, чтобы решить эту проблему, поскольку бесконечный цикл - это другой тип проблемы, который нужно решить, чем нарушение договора.

Однако сначала вы можете прочитать учебник о том, как использовать рекурсию в функциональном программировании. Суть этого в том, что должен быть базовый случай, где он всегда останавливается, и любые рекурсивные случаи, которые вам нужно «приблизить» к базовому случаю, для некоторого определения ближе.

...