Không thể thực hiện được. Các loại bạn xác định với DEFTYPE
là "các loại có nguồn gốc". Kiểu dẫn xuất được mở rộng (như macro) thành một bộ định kiểu kiểu "thực", không thể chứa các kiểu có nguồn gốc. Tất cả các tham chiếu đến các kiểu dẫn xuất (chính là kiểu hoặc các kiểu khác) bên trong phần mở rộng cũng được mở rộng. Vì vậy, kiểu đệ quy sẽ đi vào một vòng lặp infite để thử và mở rộng.
Trivial Types cung cấp loại cho danh sách phù hợp, nhưng điều đó không thực sự kiểm tra các loại phần tử mặc dù lấy nó làm đối số. Vì lý do thẩm mỹ mà sẽ là đủ.
(ql:quickload :trivial-types)
(use-package :trivial-types)
(typep '("qwe" "asd" "zxc") '(proper-list string)) ;=> T
(typep '("qwe" "asd" "zxc" 12) '(proper-list string)) ;=> T
Nếu không, bạn có thể xác định loại kiểm tra xem các phần tử cặp đầu tiên có đúng loại hay không. Điều đó ít nhất sẽ bắt được những vi phạm rõ ràng nhất.
(deftype list-of (a)
`(or null (cons ,a (or null (cons ,a (or null (cons ,a list)))))))
(typep '("asd") '(list-of string)) ;=> T
(typep '("asd" 12) '(list-of string)) ;=> NIL
(typep '("asd" "qwe") '(list-of string)) ;=> T
(typep '("asd" "qwe" 12) '(list-of string)) ;=> NIL
(typep '("asd" "qwe" "zxc") '(list-of string)) ;=> T
(typep '("asd" "qwe" "zxc" 12) '(list-of string)) ;=> T
Nếu bạn muốn nó hoạt động trong danh sách có độ dài bất kỳ, bạn sẽ phải xác định loại cho từng danh sách khác nhau mà bạn cần.
(defun list-of-strings-p (list)
(every #'stringp list))
(deftype list-of-strings()
`(or null (satisfies list-of-strings-p)))
(typep '("qwe" "asd" "zxc" "rty" "fgh") 'list-of-strings) ;=> T
(typep '("qwe" "asd" "zxc" "rty" "fgh" 12) 'list-of-strings) ;=> NIL
Có vẻ như không hữu ích khi đặt loại vì lý do thẩm mỹ. Vì lý do thẩm mỹ, tôi luôn có thể '(deftype bất cứ điều gì (a) t)', có thể không? – ssice
@ssice Sử dụng '(chuỗi danh sách thích hợp)' không kiểm tra xem danh sách đó có phải là danh sách thích hợp hay không và nó cho mọi người biết mã mà bạn mong đợi nó chứa chuỗi. Rõ ràng mã của bạn không thể dựa vào nó thực sự chứa các chuỗi, nhưng nếu nó không quan trọng thì tốt hơn là không có gì. – jkiiski
Được rồi, đó là một sự thỏa hiệp. Vì vậy, nó là "tốt" cho mã tự viết và nói những sai lầm đơn giản, mà không sâu hơn vào toán học đằng sau các loại HM. – ssice