これはできません。 DEFTYPE
で定義するタイプは「派生タイプ」です。派生型は(マクロのように)派生型を含むことができない "実"型指定子に展開されます。展開内の派生型(型自体またはその他の型)への参照もすべて展開されます。したがって、再帰的な型は無限ループに入り拡張しようとします。
Trivial Typesは、適切なリストの型を提供しますが、それを引数としてとっても要素型を実際にチェックするわけではありません。美容上の理由から、それで十分でしょう。
(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
そうでなければ、最初のカップル要素が正しい型かどうかをチェックする型を定義できます。それは少なくとも最も明白な違反をキャッチするだろう。
(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
あなたはそれが任意の長さのリストのために仕事をしたい場合は、あなたが必要とする各別のリストの型を定義する必要があります。
(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
美容上の理由からタイプを設定するのはあまり役に立ちません。美容上の理由から、私はいつも '(どのようなものであっても)'できますか? – ssice
@ssice '(正しいリスト文字列)'を使うと、リストが適切なリストであることをチェックし、文字列を含むことを期待するコードを人々に伝えます。明らかに、あなたのコードは実際に文字列を含むことに依存することはできませんが、それが重要でない場合は、それは何もないよりも優れています。 – jkiiski
申し訳ありません、それは妥協です。したがって、HM型の背後にある数学を深めることなく、自己文書化コードと直接的な間違いを言うのは「良い」です。 – ssice