Non è possibile. I tipi definiti con DEFTYPE
sono "tipi derivati". Il tipo derivato viene espanso (come una macro) in un identificatore di tipo "reale", che non può contenere tipi derivati. Vengono inoltre espansi tutti i riferimenti ai tipi derivati (sia il tipo stesso che altri) all'interno dell'espansione. Quindi il tipo ricorsivo entrerà in un ciclo di infetti per tentare di espandersi.
Trivial Types fornisce un tipo per gli elenchi corretti, ma che in realtà non controlla i tipi di elemento nonostante lo assuma come argomento. Per ragioni estetiche sarebbe sufficiente.
(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
In caso contrario, è possibile definire un tipo che verifica se i primi elementi della coppia sono di tipo corretto. Ciò catturerebbe almeno le violazioni più evidenti.
(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
Se si desidera lavorare per le liste di qualsiasi lunghezza, si dovrà definire un tipo per ogni lista diversa è necessario.
(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
Non sembra troppo utile per impostare i tipi per motivi estetici. Per ragioni estetiche posso sempre '(deftype qualunque (a) t)', non posso? – ssice
@ssice Usando '(stringa-lista corretta)' controlla che la lista sia una lista corretta, e dice alla gente che legge il codice che si aspetta che contenga stringhe. Ovviamente il tuo codice non può contare su di esso che contiene davvero stringhe, ma se non è critico, allora è meglio di niente. – jkiiski
Va bene, è un compromesso. Quindi è "buono" per il codice di auto-documentazione e per raccontare errori semplici, senza approfondire la matematica dietro i tipi di HM. – ssice