2012-05-23 38 views
1

我喜歡用自己的數據類型構建REPL,但我不喜歡一遍又一遍地編寫所有相同的模式函數。如何在列表上映射宏 - 或 - 如何使用宏定義數據類型

所以這是一個困擾我的堅果。

我有我自己的一套基本數據類型(define primitives '("mytrue" "myfalse" "mynumber" ...))

我也有(define primitiveTesters (list "mytrue?" "myfalse?" "mynumber?" ...)

現在的問題是,我只是想申請(圖)或宏來獲得數據類型?程序,基本上只是檢查記錄(mynumber . (.))的汽車是否存在。

所以最後類似(mynumber? (car (mynumber.(1.))) => #t的東西。但爲此我需要(define mynumber? (lambda (...)(...))

我的定義批量宏看起來像這樣,但我只是沒有運氣注入<variable>

(define-syntax define-batching 
(syntax-rules() 
((_ value expr)(define value expr)) 
((_ value) value) 
((_ value1 value2 ...) (begin (define value1 expr) (define-batching test2...))) 
)) 

那麼我有沒有達到計劃的死衚衕?

我見過類似的東西,我想在Emacs Lisp中。

什麼,我到底追求的是:

(define checker '(audi? volkswagen? mercedes?)) 
(define datatype '(audi volkswagen mercedes)) 

(map define-checker checker datatype) 
or 
(define-checker (car checker) (car datatype)) 
+0

對於(地圖定義檢查器檢查數據類型),你不能在一個列表映射宏。在(define-checker(car checker)(car datatype))中假設define-checker是一個宏,擴展發生在* compile-time *之前,checker還沒有值。這發生在*運行時*。如果你需要在編譯時使用列表值(而不是語法對象,那麼你需要查看更高級的宏系統,但請參閱下面我的答案的附錄。 – soegaard

回答

2

如果我理解問題的權利,你需要一個宏 定義自己的類型檢查?

下面是做到這一點的一種方法:

(define-syntax define-checker 
    (syntax-rules() 
    [(define-checker name tag) 
    (define (name object) 
     (and (list? object) 
      (not (null? object)) 
      (eq? (car object) 'tag)))])) 

(define-checker my-car? car) 

(my-car? '(car audi black)) ; evaluates to #t 
(my-car? '(truck ford pink)) ; evaluates to #f 

附錄:

如果你寫

(define checker '(audi? volkswagen? mercedes?)) 
(define datatype '(audi volkswagen mercedes)) 

值將在運行時可用。 因此你需要一個不同的方法。

例如,你可以寫:

(define-checker+datatype (audi? audi) (volkswagen? volkswagen?)) 

下面是代碼:

(define-syntax define-checker 
    (syntax-rules() 
    [(define-checker name tag) 
    (define (name object) 
     (and (list? object) 
      (not (null? object)) 
      (eq? (car object) 'tag)))])) 


(define-syntax define-checkers+datatype 
    (syntax-rules() 
    [(define-checkers+datatype (name tag) ...) 
    (begin 
     (define-checker name tag) 
     ...)])) 

(define-checkers+datatype (audi? audi) (wv? wv)) 


(audi? '(audi black)) 
+0

看我的問題 –

+0

好吧,我明白了。 你提供了很好的選擇。需要很多支持。 –

0

define-syntax是衛生的,這意味着它不能在父母的環境影響,這意味着它不能在它定義符號。 您可以嘗試使用er-,ir-宏變換器,它們允許您顯式重命名符號。

關鍵字您體系文件到Google是「ER-宏觀transformet」和「紅外宏觀變壓器」

+0

關於'syntax-rules';在宏內部定義'沒有什麼問題,特別是在這種情況下,'value'標識符被用戶傳入,所以定義將是可見的。 – leppie

+0

'syntax-rules'是衛生的,但'syntax-case'轉換器可能會產生不衛生的宏。你可以引入新的符號來用'datum-> syntax'打破衛生。 – FooBee