1

I made a program that is supposed to put all the elements that are true for the predicate in a list. It does work but not for things like >, <, etc. It only works for things like zero? and negative? How can I make it so it works for <, >, etc?

(define (divide1 pred? ls)
 (if (null? ls) '()
    (if (pred? (car ls))
        (cons (car ls) (divide1 pred? (cdr ls)))
        (divide1 pred? (cdr ls)))))

~(divide1 zero? '(0 0 4 5))
(0 0)
~(divide1 < '(0 -5 8 5))
(-5 5) <- I think...
4

2 回答 2

0

In your function, the predicate is given just one argument. That makes it work for predicates like zero?, but not for predicates taking two arguments, like < and >

One possible change to make it compare successive pairs in a list, and then return the elements that satisfies the predicate is this:

(define (divide2 pred? ls)
 (cond ((or (null? ls) (null? (cdr ls))))
        '()
       ((pred? (car ls) (cadr ls))
        (cons (car ls) (divide2 pred? (cddr ls))))
       (else
        (cons (cadr ls) (divide2 pred? (cddr ls))))))
于 2013-03-30T21:36:04.297 回答
0

You're describing the filter procedure (or divide1, as you called it):

(filter zero? '(0 0 4 5))
=> '(0 0)

The procedure receives as arguments a one-parameter predicate function and a list. That's the reason why it works for zero? and negative? (both receive a single parameter), but it will fail for <, because it expects two parameters - in other words, you have to specify what is less than what. For instance, to test for items that are less than zero using <:

(filter (lambda (x) (< x 0)) '(0 -5 8 5))
=> '(5)

In conclusion: to make it work for <, >, etc. you'll have to pass a lambda where one of the arguments is a fixed value (0 in the above example) and the other is the current element from the list (x in the previous example.)

于 2013-03-30T22:27:08.497 回答