В Common Lisp (ClozureCL) какое выражение дает значение типа `(SIMPLE-ARRAY ARRAY (5 3 *))`?

Я пытаюсь изучать CL, используя ClozureCL, и я нахожусь в центре Google Lisp Koan.

Предупреждение спойлера: я даю ответ, чтобы сформулировать свой вопрос, потому что если я не сделаю этого, отправленные ответы могут быть не такими целевыми.


Код здесь показывает значение 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))))

Я не чувствовал, что я многому научился, хотя за пределами шаблона, используемого в нотации типов. Я хотел посмотреть, смогу ли я пройти тест, используя значение x в виде (type-of ...) так что я могу связать фактические значения с типами на примере.

Тем не менее, вот мое текущее необразованное предположение. Утверждение я пометил ; <!> терпит неудачу для моего первого выбранного значения для 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> решает коан?

Наблюдения до сих пор:

  • Вот, (type-of x) является (SIMPLE-ARRAY T (5 3 33)) что, очевидно, не то, что я хочу. я хочу (SIMPLE-ARRAY ARRAY (5 3 *)) с векторными элементами.
  • Похоже, я могу указать только размеры, используя fixnum значения и настройки :adjustable t делает массив "явно настраиваемым", что, очевидно, означает, что массив больше не является SIMPLE-ARRAY,

2 ответа

Решение

Я не думаю, что есть решение для этого. На самом деле, возможно, что вы могли бы найти решение в некоторых реализациях CL, но нет никаких гарантий по этому поводу. Спецификация TYPE-OF не вдаваться в подробности о спецификаторе типа, возвращаемого в большинстве случаев, просто требуя, чтобы

(typep object (type-of object))

должно быть правдой, наряду с несколькими другими мерами. Но нет ничего конкретного для массивов.

Я не думаю, что какие-либо реализации будут когда-либо возвращать спецификаторы типа, содержащие * в измерениях для типа массива. Скорее всего, они либо возвратят очень общий спецификатор типа, который полностью пропускает измерения, либо очень специфический, который содержит фактические измерения данного массива.

Ничто не мешает реализации возвращать спецификатор типа, подобный тому, который вы ищете, но это было бы довольно извращенно. Учитывая трехмерный массив, почему он определенно решил сделать последнее измерение неопределенным, а не одно или все остальные?

Я не чувствовал, что я многому научился, хотя за пределами шаблона, используемого в нотации типов.

Возможно, вы узнали несколько вещей:

  • Common Lisp имеет объявления типов для многомерных массивов с типами элементов и указанными размерами и подстановочными знаками.

  • Есть подтипы этих типов и функция для проверки отношений подтипа (SUBTYPEP)

  • есть простые массивы (не смещенные, без указателя заполнения, не настраиваемые явно) и непростые массивы

  • тип элемента, который вы передаете MAKE-ARRAY не обязательно тип элемента созданного массива (см. функцию UPGRADED-ARRAY-ELEMENT-TYPE)

*

Другие вопросы по тегам