Нарушение контракта

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

(define (rising-numbers n)
  (if(zero? (truncate n))
     (modulo n 10)
     (> (modulo n 10) (rising-numbers (quotient n 10)))))

(rising-numbers 123)

Это ошибка, которую я получаю:

>: contract violation
expected: real?
given: #t
argument position: 2nd
other arguments...:

person Seol    schedule 13.02.2018    source источник
comment
Вот небольшое выражение, вызывающее ту же ошибку: (> 2 #true). Надеюсь это поможет.   -  person Ben Greenman    schedule 14.02.2018


Ответы (2)


Просто взглянув на вашу функцию, я вижу, что она возвращает число, когда (zero? (truncate n)), и логическое значение, если оно ложно. Причиной этого является тот факт, что > всегда возвращает логическое значение #t или #f. Хотя возврат разных типов является особенностью языка, обычно возникает ошибка, когда он становится непредсказуемым во время выполнения.

Согласно сообщению об ошибке, вы указали логическое значение в качестве одного из аргументов >. Таким образом, проблема заключается в единственном месте, где вы используете >:

(> (modulo n 10) (rising-numbers (quotient n 10)))

Здесь вы вводите (rising-numbers (quotient n 10)) в качестве числового аргумента, но поскольку мы уже установили в первом разделе, это может возвращать логическое значение, вы не можете использовать это значение в качестве второго аргумента в >.

Итак, как сделать это правильно. Хорошо. Как всегда у нас есть базовый случай:

(rising-numbers 2); ==> #t

Теперь случай по умолчанию должен делать это:

(rising-numbers 123)                             ; ==
(and (<= 2 3) (rising-numbers 12))               ; ==
(and (<= 2 3) (and (<= 1 2) (rising-numbers 1))) ; ==
(and #t #t)                                      ; ==> #t

В этом случае rising-numbers никогда не возвращает числа, всегда логические значения, и вам нужно проверять текущее и следующее значение на каждом шаге. Фактически вы получаете один базовый случай и сравнение n-1 между текущей и следующей цифрой.

person Sylwester    schedule 13.02.2018

Этот вопрос идеальный для степпера. Убедитесь, что уровень языка «Начинающий студент», не вводите ничего, кроме кода, который вы вставили в окно определений, и нажмите «Шаг». Я думаю, вы увидите проблему довольно быстро!

person John Clements    schedule 13.02.2018