确定超类型路径

时间:2013-10-13 13:21:27

标签: lisp common-lisp clisp gnu-common-lisp

给定内容为1的变量,我知道它至少是五种类型的成员:

 1 (let* ((fred 1))
 2   (princ (typep fred 'bit)) (terpri)
 3   (princ (typep fred 'integer)) (terpri)
 4   (princ (typep fred 'fixnum)) (terpri)
 5   (princ (typep fred 'rational)) (terpri)
 6   (princ (typep fred t)) (terpri))
T
T
T
T
T

这里有两个问题。

  1. 给定具有任意内容的变量,如何确定其超类型路径?

  2. 我在哪里可以找到文档中的答案?

2 个答案:

答案 0 :(得分:12)

类型

您询问的是类型,而不是。 您不能期望对您的问题有一个好的答案,因为您的号码1所属的类型远远超过您真正关心的类型。 如,

(typep 1 '(integer -6 42))
==> T

如果您将注意力限制在Standardized Atomic Type Specifiers,则可以使用类似

的内容
(defconstant *Standardized-Atomic-Type-Specifiers* ...) ; see Figure 4-2
(sort (remove-if-not (lambda (type) (typep 1 type)) 
                     *Standardized-Atomic-Type-Specifiers*)
      #'subtypep)
==> (BIT FIXNUM UNSIGNED-BYTE SIGNED-BYTE INTEGER RATIONAL REAL NUMBER ATOM T)

现在,如果您愿意将自己的兴趣限制在,那么情况会变得更易于管理。

首先,CLOS支持multiple inheritance,因此“超类路径”不是先验唯一定义的。

但是,已定义以确定method precedence order,此“路径”称为class precedence list。它由标准MOP函数compute-class-precedence-list计算:

(compute-class-precedence-list (class-of 1))
==> (#<BUILT-IN-CLASS INTEGER> #<BUILT-IN-CLASS RATIONAL> #<BUILT-IN-CLASS REAL>
     #<BUILT-IN-CLASS NUMBER> #<BUILT-IN-CLASS T>)

存在于大多数Common Lisp实现中(使用aproposfind-all-symbols来查找从中导出的包)。

您可以使用class-name来获取类的名称而不是它们的元对象:

(mapcar #'class-name (compute-class-precedence-list (class-of 1)))
==> (INTEGER RATIONAL REAL NUMBER T)

请注意,bitfixnumunsigned-bytesigned-byteatom不在此列表中,因为它们未命名标准classes ,只是types

答案 1 :(得分:2)

这不容易,IIRC。

我会以某种方式使用CLOS:

CL-USER 34 > (loop for c = (class-of 1)
                   then (first (class-direct-superclasses c))
                   collect (class-name c)
                   until (eq c (find-class t)))
(FIXNUM INTEGER RATIONAL REAL NUMBER T)

请注意,您需要CLOS实施提供的CLASS-DIRECT-SUPERCLASSES