Как исправить ошибки нарушения контракта в схеме DrRacket? - PullRequest
1 голос
/ 16 июня 2020
(define is1?
  (lambda (tuple)
    (if (and (= 2 (length tuple))
             (= 1 (- (cadr tuple) (car tuple)))
             (list? tuple))
        #t
        #f)))

(define greenlist?
  (lambda (x) (andmap is1? x)))

(greenlist? '((2 4 6) (5 6) (1 2)))
(greenlist? '(3 4 5 6))

Вторая команда: (greenlist? '(3 4 5 6)) возвращает ошибку, когда должна возвращать false. Вместо этого я получаю эту ошибку:

длина: нарушение контракта
ожидается: список?
указано: 3

Что мне следует изменить в моем коде, чтобы он возвращает false вместо ошибки?

Вот определение зеленого списка:

Зеленый список - это непустой список пар целых чисел, где пара целых чисел является списком ровно двух целых чисел, и каждая пара '( x y) имеет свойство y - x = 1.

Пример: '((5 6) (3 4) (2 3) (-5 -4)) - это зеленый список.

1 Ответ

4 голосов
/ 16 июня 2020

Проблема в том, что порядок условий имеет значение : в выражении and условия оцениваются в порядке слева направо, если одно условие - false, тогда другие условия пропущено (оценка короткого замыкания).

Ваш ввод представляет собой список списков, поэтому вы должны проверить сначала , если текущий элемент является фактическим списком - в противном случае вы попытаетесь взять length объекта, который не является списком (число 3 в вашем примере), что является ошибкой.

Между прочим: код можно упростить, на самом деле вы этого не делаете нужно использовать if, просто верните значение условия:

(define is1?
  (lambda (tuple)
    (and (list? tuple) ; you must ask this first!
         (= 2 (length tuple))
         (= 1 (- (cadr tuple) (car tuple))))))
...