Question

I'm trying to write a predicate function that returns TRUE when a list is defined to be a zipper. A zipper is defined as a proper list where each element is a list with exactly two elements and can be any expressions.

An example being

(zipper? '((a 1)(b 2)))
#t
(zipper? '((a (1)) ((b) 2)))
#t
(zipper? '((a 1 2)(b 1)))
#f

I tried to first check if the argument list is full and return false, then check the car of the list to its length of elements, and pass the cdr of the list back though my function, but I'm having trouble getting it running.

(define (zipper? l)
  (if (empty? l)
    #f
  (if (> 1 (length car(l)))
    #t
  (zipper? (cdr (l))))))

any idea what I'm doing wrong and how I can fix it? I'm still learning scheme.

Was it helpful?

Solution

For this case, it's better to use a cond than a series of nested ifs, 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))

OTHER TIPS

your parenthesis are wrong

(define (zipper? l)
  (if (empty? l)
    #f
  (if (> 1 (length (car l)))
    #t
  (zipper? (cdr l))))))

The function is always the first element in an expression, the rest are arguments. And it doesn't quite match the specification

(define (zipper? l)
  (if (empty? l)
    #t
    (if (not (=  2 (length (car l))))
        #f
        (zipper? (cdr l))))))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top