1
\$\begingroup\$

Here is a function that checks whether an alement a is a member of every set in list l-set.

I don't like the fact that it returns #t for an empty list of sets. What would be a clean fix to this problem?

(define memberall
  (lambda (a l-set)      
    (cond
      ((null? l-set) #t)
      ((not (member a (car l-set))) #f)
      (else (memberall a (cdr l-set))))))
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

so this is not a question about code, but about conventions. Usually to say "a condition holds for all elements of a set" is the same as "there's no such element in the set that the condition doesn't hold for it". Which there clearly is no such element, in an empty set. So by convention all such "all-are-true" predicates hold for an empty set.

But if you want your function to return #f in such a case, just add simple entry check for this, and convert what you have right now into an inner (nested) definition:

(define memberall
  (lambda (a l-set) 
    (and (not (null? l-set))
      (letrec ((alltrue 
                 (lambda (l-set)
                   (cond
                     ((null? l-set) #t)
                     ((not (member a (car l-set))) #f)
                     (else (alltrue (cdr l-set)))))))
        (alltrue l-set)))))

Or with named let:

(define memberall
  (lambda (a l-set) 
    (and (not (null? l-set))
      (let alltrue ((l-set l-set))
        (cond
          ((null? l-set) #t)
          ((not (member a (car l-set))) #f)
          (else (alltrue (cdr l-set))))))))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.