TL; DR JJ відповідь правильна, але пояснення залишило мене розгубленим. Зараз я розглядаю проблему, яку ви показали як повідомлення про помилку / помилку автоматичного вівірування та / або повідомлення про помилку LTA.
say my Any $Any; # (Any)
say my Hash $Hash; # (Hash)
say my Hash[Int] $Hash-Int; # (Hash[Int])
$Any<a> = 42; # OK
$Hash<a> = 42; # OK
$Hash-Int.new<a> = 42; # OK
$Hash-Int<a> = 42; # must be an object instance, not a type object
Imo це помилка або досить близька до однієї.
Помилка / проблема застосовується і для масивів за тим же сценарієм:
say my Any $Any; # (Any)
say my Array $Array; # (Array)
say my Array[Int] $Array-Int; # (Array[Int])
$Any[42] = 42; # OK
$Array[42] = 42; # OK
$Array-Int.new[42] = 42; # OK
$Array-Int[42] = 42; # Type check failed ... expected Array[Int] but got Array
Якщо це найкраще вважати notabug, то, можливо, повідомлення про помилку слід змінити. Хоча я погоджуюся з JJ, що повідомлення про помилку насправді є дійсним (коли ти розумієш, як працює раку, і розумієш, що відбувається), я думаю, що все-таки повідомлення про помилку LTA, якщо ми не змінимо raku (do) на dwim.
Що стосується стискаючої руки, мені не очевидно, як можна найкраще поліпшити повідомлення про помилку. І тепер ми маємо це ТАК. (див. мою думку про те, чи є ... повідомлення про помилку LTA? в останній відповіді, яку я написав .)
Ще одне рішення
Я вже спробував %
sigil для хеш-змінної, що також не працює.
JJ запропонував рішення, яке ініціалізується зі значенням з явним .new
. Але це скидає обмеження із змінної. Щоб зберегти його:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
В ідеалі це constant
не знадобиться, і, можливо, одного дня це не стане, але я думаю, що синтаксичний аналіз обмежений.