For this case, it's better to use a cond
than a series of nested if
s, they're causing you some trouble. And it's a good idea to extract the predicate that tests whether the current element is a "zip" into a separate procedure. Something like this:
(define (zip? e)
(and (list? e)
(= (length e) 2)))
(define (zipper? lst)
(cond ((null? lst) #t)
((not (zip? (car lst))) #f)
(else (zipper? (cdr lst)))))
Of course, there are several other ways to solve this problem. For example, using boolean connectors instead of conditionals:
(define (zipper? lst)
(or (null? lst)
(and (zip? (car lst))
(zipper? (cdr lst)))))
Or using Racket's andmap
(if not available, use SRFI-1's every
):
(define (zipper? lst)
(andmap zip? lst))