(define every-aux
(lambda(status predicate lst)
(cond((null? lst) status)
((cond((equal? (predicate (car lst)) #t)
(set! status #t)
(every-aux status predicate (cdr lst)))
(else (set! status #f) status))))))
开发者_JAVA百科Above Procedure returns void if predicate does not match with every element in lst?
It does not have any problem is returning #t though if predicate matches every element of lst.
Changing the last line to
(else (set! status #f) status))))))
to
(else (set! status "#f") status))))))
returns "#f" so procedure is correct.
How I can force scheme to return #f explicitly instead of just void?
Your code is very messy:
You have a
cond
inside another, butcond
is intended for multiple tests/results.There is no reason to have that
status
modified -- Scheme uses call-by-value, so this is likely not doing whatever you think it does.Specifically, there is no reason to use
(else (set! status #f) status)
-- you could just return#f
directly.The actual reason for your confusion is the weird
cond
nesting -- the secondcond
is actually used as a test, so if you make it (the innercond
) return#f
, then the whole test of the outercond
is getting#f
, which means that it (the outercond
) didn't get any true result, and resorts to returning an unspecified value (and if this is Racket, then that value is shown as#<void>
). So if you flatten the twocond
s into one, your problem will go away.Finally, if you're having problems at such a level, then you should consider using some textbook to familiarize yourself with the language. Specifically HtDP is intended to give you an easy path into getting familiar with the syntax.
@Eli Barzilay
After some I deliberation I could see the solution. Thanks for the pointers.
(define every?
(lambda (predicate list)
(if(null? list) "Empty List not allowed."
(every-aux? predicate list))))
(define every-aux?
(lambda (predicate lst)
(cond ((null? lst) #t)
((equal? (predicate (car lst)) #t) (every-aux? predicate (cdr lst)))
(else #f))))
精彩评论