Alexandre Nacache
Alexandre Nacache

Reputation: 25

How to fix contract violation errors in scheme DrRacket?

(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))

The second command: (greenlist? '(3 4 5 6)) returns an error when it should return false. Instead I get this error:

length: contract violation
expected: list?
given: 3

What should I change in my code so it returns false instead of an error?

Here is the definition of a greenlist:

A greenlist is a non-empty list of pairs of integers where a pair of integers is a list of exactly two integers and where each pair '( x y) has the property that y – x = 1.

Example: '((5 6) (3 4) (2 3) (-5 -4)) is a greenlist.

Upvotes: 0

Views: 458

Answers (1)

Óscar López
Óscar López

Reputation: 235984

The problem is that the order of the conditions matters: in an and expression the conditions are evaluated in left-to-right order, if one condition is false then the other conditions are skipped (short-circuit evaluation).

Your input is a list of lists, so you should test first if the current element is an actual list - otherwise you'll attempt to take the length of an object which isn't a list (the number 3 in your example), which is an error.

By the way: it's possible to simplify the code, you don't actually need to use an if, just return the value of the condition:

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

Upvotes: 3

Related Questions