A resposta de TL; DR JJ está certa, mas a explicação me deixou confusa. Atualmente, vejo o problema que você mostrou como um erro de autovivificação / bug e / ou mensagem de erro 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, este é um bug ou está bem próximo de um.
Um bug / problema também se aplica a matrizes no mesmo cenário:
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
Se for considerado melhor como não-bug, talvez a mensagem de erro deva ser alterada. Embora eu concorde com JJ que a mensagem de erro está realmente no ponto (quando você entende como o raku funciona e descobre o que está acontecendo), acho que, no entanto, é uma mensagem de erro do LTA se não mudarmos raku (do) para dwim.
Por outro lado, não é óbvio para mim como melhorar a mensagem de erro. E agora temos esse SO. (cf. meu argumento sobre isso em A mensagem de erro ... é LTA? em uma resposta recente que escrevi .)
Outra solução
Eu já tentei o %
sigil para a variável hash, isso também não funciona.
JJ forneceu uma solução que inicializa com um valor com um explícito .new
. Mas isso elimina a restrição da variável. Para retê-lo:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
Idealmente, constant
isso não seria necessário, e talvez um dia não seja, mas acho que a análise de características é limitada.