В Common Lisp (ClozureCL) какое выражение выдает значение типа `(SIMPLE-ARRAY ARRAY (5 3 *))`? - PullRequest
0 голосов
/ 23 мая 2018

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

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

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

Наблюдения на данный момент:

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

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

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

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

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

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

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

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

*

0 голосов
/ 23 мая 2018

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

(typep object (type-of object))

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

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

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

...