Application not a procedure (Scheme map procedure)

2019-09-06 02:25发布

问题:

I am attempting to write my own simplified map procedure in R5RS. In short, it takes a procedure and two lists, and returns a list with the results of the procedure called on every pair of objects in the two argument lists, until either is empty.

This works fine for arithmetic operators, such as:

(map2-rec + '(1 2 3) '(1 2 3 4))

However, when I attempt to pass an anonymous lambda function (the return value of my both? procedure) which returns either #t or #f, this does not work.

(define (map2-rec proc items1 items2)
  (if (or (null? items1) (null? items2))
      '()
      (cons (proc (car items1) (car items2))
            (map2-rec proc (cdr items1) (cdr items2)))))


(define (both? proc)
  (lambda (item1 item2)
    ((if (and (proc item1) (proc item2))
         #t
         #f))))

The specific error I am receiving in DrRacket is:

application: not a procedure;  
expected a procedure that can be
applied to arguments   
given: #t   
arguments...: [none]

If someone could tell me how I can correct this error, I'd be very happy. I cannot understand why this code fails myself.

回答1:

There's an extra (and erroneous) pair of parentheses in both?, surrounding the if expression. This should fix it:

(define (both? proc)
  (lambda (item1 item2)
    (if (and (proc item1) (proc item2))
        #t
        #f)))

Now your procedure works as expected:

(map2-rec + '(1 2 3) '(1 2 3 4))
=> '(2 4 6)
(map2-rec (both? even?) '(1 2 3) '(1 2 3 4))
=> '(#f #t #f)