我正在尝试使用ClozureCL学习CL,并且正在Google的Lisp koans中间。
剧透警告:我给出一个答案来构建我的问题,因为如果我不这样做,提交的答案可能不会那么有针对性。
此处的代码显示传递的值x
。
(define-test test-guess-that-type!
(let ((x '(SIMPLE-ARRAY ARRAY (5 3 *))))
(assert-true (subtypep x '(SIMPLE-ARRAY T (* 3 *))))
(assert-true (subtypep x '(SIMPLE-ARRAY T (5 * *))))
(assert-true (subtypep x '(SIMPLE-ARRAY ARRAY *)))
(assert-true (typep (make-array '(5 3 9) :element-type 'STRING ) x))
(assert-true (typep (make-array '(5 3 33) :element-type 'VECTOR ) x))))
除了类型符号中使用的模式之外,我觉得我没有学到很多东西。我想看看我是否可以使用(type-of ...)
形式的值x
通过测试,以便我可以通过示例将实际值与类型相关联。
也就是说,这是我目前没有受过教育的猜测。我用; <!>
标记的断言对于我为x
选择的第一个值失败。
(define-test test-guess-that-type!
(let ((x (type-of (make-array '(5 3 33) :element-type 'VECTOR))))
(assert-true (subtypep x '(SIMPLE-ARRAY T (* 3 *))))
(assert-true (subtypep x '(SIMPLE-ARRAY T (5 * *))))
(assert-true (subtypep x '(SIMPLE-ARRAY ARRAY *)))
(assert-true (typep (make-array '(5 3 9) :element-type 'STRING ) x)) ; <!>
(assert-true (typep (make-array '(5 3 33) :element-type 'VECTOR ) x))))
我的问题是:如果你被限制使用(type-of <val>)
<val>
什么解决了koan?
迄今为止的观察结果:
- 在这里,
(type-of x)
(SIMPLE-ARRAY T (5 3 33))
,这显然不是我想要的。我想(SIMPLE-ARRAY ARRAY (5 3 *))
矢量元素。 - 看来我只能使用
fixnum
值指定维度,并且设置:adjustable t
使数组"明确可调",这显然意味着数组不再是SIMPLE-ARRAY
。
我认为没有解决方案。实际上,您可能会在某些CL实现中找到解决方案,但不能保证。在大多数情况下,TYPE-OF
规范没有详细说明返回的类型说明符,只是要求
(typep object (type-of object))
一定是真的,还有其他一些反驳。但是没有特定于数组的内容。
我认为任何实现都不会返回在数组类型的维度中包含*
的类型说明符。它们可能会返回一个完全省略维度的非常通用的类型说明符,或者返回一个包含给定数组实际维度的非常具体的说明符。
没有什么能阻止实现返回像你要找的类型说明符,但这是非常反常的。给定一个三维数组,为什么它会特别选择不指定最后一个维度而不是一个或所有其他维度?
除了类型符号中使用的模式之外,我觉得我没有学到很多东西。
您可能已经学到了一些东西:
-
Common Lisp 具有用于具有元素类型和指定维度和通配符维度的多维数组的类型声明。
-
有这些类型的子类型和用于检查子类型关系的功能(
SUBTYPEP
(
有简单数组 (不置换,没有填充指针,不能明确调整(和非简单数组
传递给
MAKE-ARRAY
的元素类型不一定是所创建数组的元素类型(请参阅函数UPGRADED-ARRAY-ELEMENT-TYPE
(
*