整数向量不是数字数组的子类型,为什么?
A vector of integers is not a subtype of arrays of numbers, why?
我们有以下内容:
CL-USER> (subtypep 'integer 'number)
T
T
CL-USER> (subtypep 'double-float 'number)
T
T
CL-USER> (subtypep 'vector 'array)
T
T
因此:
CL-USER> (subtypep '(vector integer) '(array number))
T
T
但我不明白:
CL-USER> (subtypep '(vector double-float) '(array number))
NIL
T
我正在使用 SBCL 1.3。1.debian x86_64,以防这取决于实现。谢谢!
(array foo)
是否是 (array bar)
的子类型取决于实现是否在内存中具有 foo
和 bar
类型值数组的打包表示。如果实现对其中一种元素类型有更紧凑的表示(例如,为了避免内存表示中的间接级别),则数组类型不兼容,因此 subtypep
returns false。如果实现使用相同的打包表示或通用表示,则 subtypep
returns true.
特别是,函数 (lambda (foo bar) (subtypep `(array ,foo) `(array ,bar))
的行为取决于实现。
例如,(array integer)
在 SBCL 和 CLISP 中是 (array number)
的子类型,但在 GCL 中不是。 (array double-float)
在 CLISP 中是 (array number)
的子类型,但在 GCL 或 SBCL 中不是。
这是在Common Lisp definition中指定的。
来自SUBTYPEP
:
Therefore,
(subtypep '(array T1) '(array T2)) => true
if and only if
(upgraded-array-element-type 'T1) and
(upgraded-array-element-type 'T2)
return two different type specifiers that always refer to the same sets of objects.
这是 UPGRADED-ARRAY-ELEMENT-TYPE
returns 与 SBCL 1.3.7 的内容:
CL-USER> (upgraded-array-element-type 'double-float)
DOUBLE-FLOAT
CL-USER> (upgraded-array-element-type 'number)
T
我猜如果我们尝试添加整数或复数,专门用于双浮点数的数组可能无法正常运行。规范不要求实现来保证子类型关系在这种情况下成立。
这与Covariance, Contravariance and Invariance间接相关:
Mutable data types which act as both sources and sinks should be invariant.
[...] a Cat[] cannot be treated as an Animal[]. It should always be possible to put a Dog into an Animal[].
我们有以下内容:
CL-USER> (subtypep 'integer 'number)
T
T
CL-USER> (subtypep 'double-float 'number)
T
T
CL-USER> (subtypep 'vector 'array)
T
T
因此:
CL-USER> (subtypep '(vector integer) '(array number))
T
T
但我不明白:
CL-USER> (subtypep '(vector double-float) '(array number))
NIL
T
我正在使用 SBCL 1.3。1.debian x86_64,以防这取决于实现。谢谢!
(array foo)
是否是 (array bar)
的子类型取决于实现是否在内存中具有 foo
和 bar
类型值数组的打包表示。如果实现对其中一种元素类型有更紧凑的表示(例如,为了避免内存表示中的间接级别),则数组类型不兼容,因此 subtypep
returns false。如果实现使用相同的打包表示或通用表示,则 subtypep
returns true.
特别是,函数 (lambda (foo bar) (subtypep `(array ,foo) `(array ,bar))
的行为取决于实现。
例如,(array integer)
在 SBCL 和 CLISP 中是 (array number)
的子类型,但在 GCL 中不是。 (array double-float)
在 CLISP 中是 (array number)
的子类型,但在 GCL 或 SBCL 中不是。
这是在Common Lisp definition中指定的。
来自SUBTYPEP
:
Therefore,
(subtypep '(array T1) '(array T2)) => true
if and only if
(upgraded-array-element-type 'T1) and (upgraded-array-element-type 'T2)
return two different type specifiers that always refer to the same sets of objects.
这是 UPGRADED-ARRAY-ELEMENT-TYPE
returns 与 SBCL 1.3.7 的内容:
CL-USER> (upgraded-array-element-type 'double-float)
DOUBLE-FLOAT
CL-USER> (upgraded-array-element-type 'number)
T
我猜如果我们尝试添加整数或复数,专门用于双浮点数的数组可能无法正常运行。规范不要求实现来保证子类型关系在这种情况下成立。
这与Covariance, Contravariance and Invariance间接相关:
Mutable data types which act as both sources and sinks should be invariant. [...] a Cat[] cannot be treated as an Animal[]. It should always be possible to put a Dog into an Animal[].