Ошибка схемы "приложение: не процедура" - PullRequest
0 голосов
/ 04 мая 2018

Я читаю sicp и пишу программу, чтобы найти первые 3 простых числа из 1000. Я использую измененную версию метода Ферма (однако алгоритм в данном случае не имеет значения, так как мне нужно только понять сообщение об ошибке). Весь набор кода:

(define (fz-prime number count)
    (if (< count 4)
        (if (= (fz-fermat-loop number 1) 0)
            (fz-prime (+ number 1) count)
            ((display number) (fz-prime (+ number 1) (+ count 1))))))

(define (fz-fermat-loop number count)
    count
    (if (> count 5)
        1
        (if (= (fz-fermat-test number (fz-random number)) 0)
            0
            (fz-fermat-loop number (+ count 1)))))

(define (fz-fermat-test number count)
    (if (= (modulo count number) (modulo (fz-exp-wrapper count number) number))
        1
        0))

(define (fz-random number)
    (random (- number 2)))

(define (fz-exp-wrapper base power)
    (fz-exp base power 1))

(define (fz-exp base power result)
    (if (<= power 0) result
        (fz-exp base (- power 1) (* result base))))

(fz-prime 1000 1)

Теперь каждый раз, когда я запускаю код, отображается следующая ошибка:

100910131019. . application: not a procedure;
 expected a procedure that can be applied to arguments
  given: #<void>
  arguments...:

Первые 3 числа - это первые три простых числа, но я не понимаю, что говорится в сообщении об ошибке.

1 Ответ

0 голосов
/ 04 мая 2018

Сообщение об ошибке говорит о том, что вы используете Racket, но вы также выбрали языковой уровень, который отключает полезные сообщения об ошибках, такие как сообщение, которое я получаю, когда копирую вашу программу в буфер на языке ракетки #lang:

if: missing an "else" expression in: (if (< count 4) (if (= (fz-fermat-loop number 1) 0) 
(fz-prime (+ number 1) count) ((display number) (fz-prime (+ number 1) (+ count 1)))))

На самом деле, держу пари, что вы используете превосходный язык sicp Дженса Акселя Соегарда, который является совершенно правильным выбором для работы через sicp .... но, к сожалению, отсутствуют некоторые полезные сообщения об ошибках.

В частности, на языке, который вы используете, в if может отсутствовать ветвь else, и если тест не пройден, он молча оценивает специальное значение #.

Oh! Но ждать! У тебя другая проблема ... ты пишешь

((display number) (fz-prime (+ number 1) (+ count 1)))

Могу поспорить, что вы думаете, что если вы просто возьмете два выражения, такие как (display number) и (fz-prime ...), и заключите их в скобки, это означает: «делай первое, потом делай второе». Однако на самом деле это означает, что «первое выражение вычисляется для функции; вызывайте ее с аргументами, полученными в результате вычисления оставшихся выражений», а #void - это именно то, что возвращает (display ...).

Возможно, вы ищете begin, вот так:

(begin 
   (display number) 
   (fz-prime (+ number 1) (+ count 1)))
...