Подтвердить что ты не робот

Как этот Perl чувственный, учитывая систему Perl 6?

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


Мой разум... взорвался.

Рассмотрим:

use strict;

my Int $n = 6;
my Str $x = "a";
my @l = $n, $x;
say @l ~~ List;

Печать True, как и ожидалось.

Рассмотрим, что:

use strict;

my Int $n = 6;
my Str $x = "a";
my List @l = $n, $x; # <-- only change is the type notation
say @l ~~ List;

Что умирает с:

Type check failed in assignment to @l; expected List but got Int

Итак... тип List is List, но я не могу сказать его List, потому что это грех!

Что здесь происходит? Это ошибка? Или я приношу свои неулокальные Python и Go идиомы в Perl и нарушающие вещи?

4b9b3361

Ответ 1

my List @l = $n, $x;

не делает то, что вы думаете. Он не заявляет, что @l является List. Он объявляет, что элементы @l будут List s. Вам не нужно объявлять, что @l будет массивом; вы уже это сделали, когда использовали сигил.

Вы можете переместить взрыв вокруг, заменив List на Int, чтобы Perl 6 ожидал список Int s.

Ответ 2

my List @l;

- сокращенное обозначение для

my @l is Array of List;

который помещает ограничение типа List на элементы массива.

Ограничение типа на контейнере уже выражено через синтаксис @, соответствующий роли Positional, тогда как a % sigil соответствует роли Associative.

Случай переменных $ аналогичен тому, что и контейнер (a Scalar) с ограничением на его единственный элемент. Тем не менее, ограничение также позволяет прямое переуплотнение с деконтернализованным значением 1.


1 Если приведенное выше не имеет для вас смысла, вы должны изучить разницу между присваиванием = и привязкой :=. Также может быть поучительным проверить переменную с помощью .VAR.WHAT.

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

Это можно использовать для разрушения системы типов:

my Int $a;
my $b = 42;
$a := $b;
$b = "not cool";
say $a;

Не круто: (