2014-02-18 3 views
0

Я пытаюсь написать свою упрощенную процедуру карты в R5RS. Короче говоря, он принимает процедуру и два списка и возвращает список с результатами процедуры, называемой каждой парой объектов в двух списках аргументов, до тех пор, пока они не будут пустыми.Приложение не процедура (процедура схемы схемы)

Это прекрасно работает для арифметических операторов, таких как:

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

Однако, когда я пытаюсь передать анонимную функцию лямбда (возвращаемое значение как моя процедура?), Которая возвращает либо #t или #F , это не работает.

(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)))) 

Специфическая ошибка я получаю в DrRacket является:

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

Если кто-то может сказать мне, как я могу исправить эту ошибку, я был бы очень рад. Я не могу понять, почему этот код не работает сам.

+1

возможно дубликат [ «приложения: не процедура» в бинарных арифметических процедур] (http://stackoverflow.com/ Вопросы/19022704/application-not-a-procedure-in-binary-арифметические-процедуры) Эта проблема обычно возникает, когда у вас есть дополнительный набор круглых скобок (в этом случае он находится в '((if ... #t #f)), так что результат '(if ... #t #f)' (в этом случае '# t') вызывается как процедура (но это не процедура). –

+2

Кроме того,' (и ... ...) 'уже возвращает логическое значение;' (if test #t #f) 'эквивалентно t o 'test'. Вы должны использовать '(define (both? Proc) (lambda (item1 item2) (и (proc item1) (proc item2))))'. –

+0

@JoshuaTaylor 'и' необязательно возвращает логическое значение (например: '(и 1 2)') - хотя это будет отлично работать с примером OP, но если по какой-то причине 'both?' _must_ return only '# t' или '# f', нормально использовать' if' –

ответ

4

Существует дополнительная (и ошибочная) пара круглых скобок в both?, окружающая выражение if. Это должно исправить:

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

Теперь ваша процедура работает, как ожидалось:

(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) 
+0

Вау, вот и все! Огромное спасибо. Я отвечу, как только таймер будет готов :) –

+0

@ HenrikHillestadLøvold не проблема, это было мое удовольствие :) –

+0

@ Ответ Хенрика Оскара прав, конечно, но вы можете (и должны) покончить с «если» вообще , и просто верните '(и (proc item1) (proc item2))' непосредственно. –

Смежные вопросы