2010-07-09 7 views
8

Aynı türdeki şeylerin bir listesini açıklayan bir tür belirtici tanımlamak istiyorum. Bu yüzden (array integer) (dahili) benzeri (list-of integer) olmasını istiyorum. Bunun gibi belirli bir türü için bunu oluşturmak mümkün duyuyorum:Common Lisp'te, genel bir veri türü belirteci nasıl tanımlanır (tamsayıların listesi gibi)?

(defun elements-are-integer (seq) 
    (every #'(lambda (x) (typep x 'integer)) seq)) 
(deftype list-of-integer() 
    '(and list (satisfies elements-are-integer))) 

Ancak bu Yapılabilecek her türü için bunu yapmak zorunda anlamına gelir. Bu kodu nasıl değiştirebilirim ki, tür bir argüman olarak başka bir tür alır ve satisfies yüklemini anında oluşturur mu? Sorun şu ki, satisfies, global bir sembol gerektiriyor ve yüklemeyi doğru bağlamda nasıl tanımlayacağımı bilmiyorum (sanırım bir şekilde gensym'a ihtiyacım var, ama nasıl?). Ayrıca çözüm, türün başka bir paketin içinde oluşturulabilmesi için çalışmalıdır.

cevap

-1

Ben Örneğin (deftype-list-of integer) için

(defmacro deftype-list-of (type) 
    (let* ((etfname (intern (concatenate 'string "ELEMENTS-ARE-" 
             (symbol-name type)))) 
     (ltname (intern (concatenate 'string "LIST-OF-" 
             (symbol-name type)))) 
     (tcdef `(defun ,etfname (seq) 
        (every (lambda (x) (typep x ',type)) seq))) 
     (ltdef `(deftype ,ltname() 
        '(and list (satisfies ,etfname))))) 
    (if (fboundp etfname) 
     ltdef 
     `(progn ,tcdef ,ltdef)))) 

birine denk kodlamak için genişler ... Ben deftype için kullanılır, ancak bu makro yapmalı tam olarak ne olduğunu anlamak için yeterli ortak lisp bilmiyorum itiraf etmeliyim gönderdin.

Bu kod, geçerli paketin türünü (varsayalım) tanımlar, ancak paket adını kabul etmek için değiştirmenin önemsiz olması gerekir.

+0

teşekkür ederiz. Tam olarak istediğim gibi olmasa da kesinlikle yararlıdır. –

12

bu deneyin:

(defun elements-are-of-type (seq type) 
    (every #'(lambda (x) (typep x type)) seq)) 

(deftype list-of-type (type) 
    (let ((predicate (gensym))) 
    (setf (symbol-function predicate) 
     #'(lambda (seq) (elements-are-of-type seq type))) 
    `(and list (satisfies ,predicate)))) 

(typep '(1 2 3) '(list-of-type integer)) 
; -> T 

(typep '(1 2 a) '(list-of-type integer)) 
; -> NIL 

(typep '(a b c) '(list-of-type symbol)) 
; -> T 
İlgili konular