2012-03-07 72 views
1

我試圖編寫一個宏來檢查一個列表,看看是否有一個過程調用,但我不太清楚如何去做。我頭上的第一件事就是使用這個程序?函數來檢查,但它不起作用。什麼即時試圖做的一個例子是:如何檢查一個符號是否是一個過程

(procedure? (car '(+ 1 2))) 

現在,該名單的車返回+,但功能還是返回false

有沒有辦法檢查列表的車是否是程序?

回答

2
(car '(+ 1 2)) => '+ not + 

+是一個過程,但「+只是一個符號!

你應該檢查帶引號的變量:

(procedure? (car (list + 1 2))); => #t 
;or 
(procedure? (car `(,+ 1 2))); =>#t 

如果列表的形式「(ABCD),你可以用這種方式檢查:

(procedure? (eval (car '(+ 1 2)) (interaction-environment)));=>#t 

因爲:

(eval (car '(+ 1 2)) (interaction-environment)) 
;=>(eval '+ (interaction-environment)) 
;=>+ 

我不認爲你在這裏需要一個宏,一個函數就足夠了。 抽象發揮功能:

(define (application-form? lst) 
     (procedure? (eval (car lst) (interaction-environment)))) 
+0

如果列表的「car」是未綁定的符號,則會引發錯誤。 (我恐怕這實際上不是一個可移植的問題,儘管...) – 2012-03-07 10:07:33

+0

我明白了,但是,考慮一下情況:(application-form?'((lambda(x)x)1)),當然是汽車部分(lambda(x)x)是一個過程,但它返回#f – FooBee 2012-03-07 13:04:44

+0

和所有類型的謂詞包括「過程?」 「對?」 「名單?」在其參數未被綁定的情況下產生錯誤。因此,我認爲我們的過程應該具有相同的行爲。 – FooBee 2012-03-07 13:11:36

1

如果列表的car被允許未結合的符號,這個問題不是可移植可溶的。但是,您可以在Guile中解決這個問題:

(define (procedure-symbol? x) 
    (and (symbol? x) 
     (let ((var (module-variable (interaction-environment) x))) 
     (and var 
       (variable-bound? var) 
       (procedure? (variable-ref var)))))) 

(define (application-form? lst) 
    (procedure-symbol? (car lst))) 
相關問題