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 в том, что сообщение об ошибке действительно присутствует (когда вы понимаете, как работает raku и выясняете, что происходит), я думаю, что это, тем не менее, сообщение об ошибке LTA, если мы не изменим raku (do) на dwim.
С другой стороны, для меня не очевидно, как лучше всего улучшить сообщение об ошибке. И теперь у нас есть это ТАК. (см. мою точку зрения об этом в Является ли ... сообщение об ошибке LTA? в недавний ответ, который я написал .)
Другое решение
Я уже попробовал сигил %
для переменной ha sh, которая тоже не работает.
JJ предоставил решение, которое инициализируется значением с явным .new
. Но это снимает ограничение с переменной. Чтобы сохранить его:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
В идеале constant
не понадобится, и, возможно, однажды он не понадобится, но я думаю, что разбор признаков ограничен.